Search code examples
fortrannumerical-recipes

Fortran compiler differences in treating properties as 'save attributes'?


We have this old Fortran script that we're trying to recompile using Intel's Visual Fortran but we get calculation errors and different results than the old compiled version of the code.

We found what we believe to be the problem in the code below (which is loosely from Numerical Recipes).

The problem is that the 'it' parameter is reset for each call, it should however be stored between the function calls.

Our best guess for what might be the problem is that an older compiler might have treated 'it' as a 'save attribute' and therefore stored it between the function calls.

We may be completely wrong here and if some Fortran-guru can confirm this or have a better explenation we would love some help!

      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

Solution

  • Yes, the explanation is plausible. The code accesses variable it at

       tnm=it
    

    and this value is undefined when it is not save.

    The old compile might not have used stack at all and might have used static storage for all variables. It also might have used stack, but it never got overwritten and the value happened to be at the same place. Who knows, we don't have the information to know.

    There are compiler options to force the save attribute to all variables for bad codes like this (the SAVE for all was never standard!). It is just -save for Intel Fortran.