fortran - 函数求值与语句中的其他效果冲突

标签 fortran language-lawyer expression-evaluation

我想澄清我对 Fortran 中评估顺序的理解。
假设我有一个带有方法的 Stack 类型 poppush_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/

相关文章:

c++ - 是否有任何 C++11 线程安全保证适用于使用 C++11 编译/链接的第三方线程库?

c++ - 类模板的成员函数的显式实例化声明是否会导致类模板的实例化?

c++ - 为什么不同的 C++ 编译器对此代码给出不同的结果?

fortran - Fortran 中的 INT 与 FLOOR

c - 运行从代码生成的二进制文件是否具有 "constraint violation"实际上未定义的行为?

R:如何从字符串向量转换为引号/名称向量?

php - 如何评估用户提供的代码?

fortran 模块——查找定义/分配变量的位置

fortran - Fortran 中 maxloc 的类型冲突

fortran - gfortran 编译器标志严格遵守 Fortran 77