0

我们有这个旧的 Fortran 脚本,我们正在尝试使用英特尔的 Visual Fortran 重新编译,但我们得到的计算错误和与旧编译版本的代码不同的结果。

我们在下面的代码中发现了我们认为的问题(大致来自 Numerical Recipes)。

问题是每次调用都会重置“it”参数,但是它应该存储在函数调用之间。

我们对可能是什么问题的最佳猜测是,较旧的编译器可能已将“它”视为“保存属性”,因此将其存储在函数调用之间。

我们在这里可能完全错了,如果某些 Fortran 大师可以证实这一点或有更好的解释,我们会很乐意提供帮助!

      subroutine TrapezoidalRule(Func, a, b, s, n)
*
*     This routine performs the trapezoidal rule, see Numerical Recipes
*
      implicit none
      real*8 Func, a, b, s
      Integer*4 n
      external Func
*
      real*8 del, x, sum
      Integer*4 it, tnm, j
*
      if (n .eq. 1) then
*
         s=0.5d0*(b-a)*(Func(a)+Func(b))
         it=1
*
      else
*
         tnm=it
         del=(b-a)/dble(tnm)
         x=a+0.5d0*del
         sum=0.d0
         do 11 j=1,it
*
            sum=sum+Func(x)
            x=x+del
*
11       continue
*
         s=0.5d0*(s+(b-a)*sum/dble(tnm))
         it=2*it
*
      endif
*
      return
      end
4

1 回答 1

2

是的,这个解释是合理的。代码访问变量it

   tnm=it

it当is not时,此值未定义save

旧的编译可能根本没有使用堆栈,并且可能对所有变量都使用了静态存储。它也可能使用了堆栈,但它从未被覆盖,并且值恰好在同一个地方。谁知道呢,我们没有要知道的信息。

对于像这样的错误代码,有一些编译器选项可以强制将save属性赋予所有变量(SAVEfor all 从来都不是标准的!)。它仅-save适用于英特尔 Fortran。

于 2017-11-10T15:58:15.000 回答