我想澄清我对 Fortran 中评估顺序的理解。
假设我有一个带有方法的 Stack 类型 pop
和 push_back
.
如果我执行以下代码:
call stack%push_back(1)
call stack%push_back(3)
call stack%push_back(stack%pop() - stack%pop())
write(*, *) stack%pop() ! could print 2, or -2
堆栈上的最后一个元素取决于评估顺序,因此 answer解释说,编译器可以自由更改评估顺序。但即使我有一个可交换的操作,仍然存在问题。
Fortran 2008 标准说 (7.1.4):
The evaluation of a function reference shall neither affect nor be affected by the evaluation of any other entity within the statement.
所以即使是这段代码:
call stack%push_back(1)
call stack%push_back(3)
call stack%push_back(stack%pop() + stack%pop())
不符合标准吗?这意味着我总是必须这样写:
call stack%push_back(1)
call stack%push_back(3)
block
integer :: A, B
A = stack%pop()
B = stack%pop()
call stack%push_back(A - B)
end block
write(*, *) stack%pop() ! is guaranteed to print 2
这是真的?
最佳答案
(这里我们假设问题中事物的合理和直观的定义,并在答案中暗示相似。)
该声明
call stack%push_back(stack%pop() - stack%pop())
由于问题中所述的原因,确实是无效的。但是,根据对中的其他限制(未引用)(Fortran 2018 10.1.4,但在 F2008 中类似),可能更容易看到这一点:if a function reference causes definition or undefinition of an actual argument of the function, that argument or any associated entities shall not appear elsewhere in the same statement.
关注声明与
call stack%push_back(pop(stack) - pop(stack))
很明显 stack
是一个实际参数,并且在语句中出现不止一次; stack
由函数 pop
定义.是的,您需要使用不同的语句来达到预期的效果。问题中给出的方法是合理的。
关于fortran - 函数求值与语句中的其他效果冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65869750/