Fortran 90 intent(in) 用于递归函数

Fortran 90 intent(in) for a recursive function

下面的代码是否符合 Fortran 90 标准?

integer, pointer :: pa ! global
...

recursive subroutine foo(a)
integer, target, intent(in) :: a

  if (a > 10) then
    return
  endif

  if (associated(pa)) then
    pa = 123
  endif
  pa => a

  call foo(a + 1)

  ! use a

end subroutine foo

变量 a 是用 intent(in) 声明的,根据 Fortran 90 standard,第 5.1.2.3 节:

specifies that the dummy argument must not be redefined or become undefined during the execution of the procedure

变量 a 没有在 foo(a) 的递归级别重新定义;相反,我们保存一个指向 a 的指针,这样我们就可以在较低的递归级别上重新定义 a

换句话说:

foo(a) ! do not change a, save the pointer to a
  foo(a + 1) ! change a, save the pointer to a + 1
    foo(a + 1 + 1) ! change a + 1, save the pointer to a + 1 + 1, and so on.

根据我对标准的理解,foo(a + 1)的生命周期是foo(a)生命周期的一个子集,所以a不应该被改变。 编译器假设 foo() 具有 "undefined behaviour"(或 Fortran 的等价物)是否安全?

答案取决于与最初调用该过程的 a 关联的实际参数的值,以及第一次调用之前 pa 的关联状态。

如果 a 大于 10,则代码符合要求(而且不是很令人兴奋)。

如果a等于10,且pa的指针关联状态未定义,代码不符合。 associated 内在函数需要定义其实际参数。如果a等于10且pa的指针关联状态不是undefined,则代码符合。

如果 a 小于 10,则代码不合格。程序执行的第一个实例的 INTENT(IN) 虚拟参数 a 在下一个实例的嵌套执行期间通过对指针 pa 的赋值重新定义。围绕 INTENT(IN) 的规则要求非指针伪参数的值在过程的调用或执行期间不能直接或间接更改。

除了这里不相关的诊断之外,一个符合规范的 Fortran 处理器在执行不符合规范的代码时可以做任何它想做的事情,但是这里的规范与不规范是一个执行时间问题。

多年来,对 Fortran 90 标准的许多更正已有效发布,其中大部分可能是通过对后续标准的编辑进行的。以后的标准用词略有不同,但是这方面的要求没有变。