Fortran 函数引用会干扰赋值吗?

问题描述 投票:0回答:1

我知道(至少在某一点上),由于别名,以下内容在 Fortran 中是无效的

program main

integer :: x, y

! compilers assume a and b to be distinct
y = f(x, x)

contains

integer function f(a, b) result(c)
  integer, intent(in out) :: a, b
  a = 1
  b = 2
  c = a ! compiler can optimize to c = 1
end function

end program main

但是以下内容有效吗?

program main

integer :: x(3)

x = [1, 2, 3]
x = square_me(x)

contains

function square_me(a) result(squared)
  integer, intent(in out) :: a(3)
  integer             :: squared(3)
  integer             :: i

  squared = a ** 2
  a(1) = 0 ! nasty side-effect
end function

end program main

它可以在 gfortran 中运行,但我不确定它是否符合标准。

我知道函数中的副作用不是一个好主意。我正在处理超过 100k 行的遗留代码,这些代码喜欢使用 C 风格的整数代码返回函数并修改参数,所以这个问题专门与标准有关。

fortran language-lawyer gfortran
1个回答
4
投票

主程序均无效。

Fortran 中所谓的别名规则通常是指在过程执行期间应用于实体的那些限制。然而,在赋值语句中,在影响左侧之前,会先完全执行右侧的求值。

相反,破坏第二个主程序的是对函数副作用的限制。

副作用受到限制(F2018,10.1.4),除非在某些情况下不适用:

如果函数引用导致函数实际参数的定义或取消定义,则该参数或任何关联实体不得出现在同一语句的其他位置

a(1)
的赋值会导致实际参数
x
的定义,因此
x
可能不会出现在赋值语句的其他位置(包括左侧)。

函数中的副作用还有其他几个(也许令人惊讶的)限制。我们只想说:如果可以的话,请避免函数中的副作用,除非您真的了解规则,并且可以确保使用您的函数的每个人也确实了解规则。

© www.soinside.com 2019 - 2024. All rights reserved.