3

from the source code published in the programmer's manual of a commercial program, I have isolated a code snippet which puzzles me quite a lot.

The function below is expected to be called multiple times by a kernel and is supposed to implement the temporal behaviour of a component in a system consisting of many interconnected components (I have removed the Input/Output parameters from the function prototype because they are irrelevant to the point I intend to rise).

To distinguish between different instances of the same block type the kernel pass an instance number in the INFO(1) element.

As far as I have understood, the designer of this program took a great deal of effort trying to save the time spent in copying the values of the parameters from the PAR vector to local variables with meaningful names at each call (as if they were not aware of the optimizations a compiler can do). It seems to me that they wanted to assign them to the local variables only in the first call, or when the caller switch to a different instance of the same type.

However I can't understand how this could work if the local variables are not declared static with the "save" keyword. Does FORTRAN store local variables statically i.e. not on a stack? (I am sorry if the question sounds stupid, I am used to the C/C++ languages)

Thank you.

SUBROUTINE TYPE151(PAR, INFO, *)

    IMPLICIT NONE

    INTEGER*4 INFO(15), IUNIT
    DOUBLE PRECISION PAR, QMAX

    PARAMETER (NP=1)
    DIMENSION PAR(NP)

    ! First call
    IF (INFO(7).EQ.-1) THEN

        IUNIT = INFO(1)

        QMAX = PAR(1)

        RETURN 1
    ENDIF

    ! later calls
    IF(INFO(1).NE.IUNIT) THEN

        IUNIT = INFO(1)

        QMAX = PAR(1)
    ENDIF

    ! Making use of QMAX in some ways...

    RETURN 1 
END SUBROUTINE TYPE151
M. S. B.
  • 28,968
  • 2
  • 46
  • 73
  • 1
    I have not worked with FORTRAN in several decades, but historically your are correct; FORTRAN did not support recursion and stored all local variables statically. I am sure there are modern version of FORTRAN for which this is no longer true, but possibly not all of them. – Pieter Geerkens Mar 14 '13 at 16:10
  • local variable in subroutine become undefined after returning, unless it has save attribute, or it is declared in module level and the module is used by the main program. the accepted solution in following Q is good one. http://stackoverflow.com/questions/2893097/fortran-save-statement . So i dont understand how your code is working... – yosukesabai Mar 14 '13 at 16:43
  • Me neither, also considering that this pattern, published in the manual, has propagated to many user written blocks... I can't believe that everybody is compiling with the same old compiler. Thank you for your comments, but please consider that the above thing is not "my" code! – Alkhwarizmi Mar 15 '13 at 09:08

1 Answers1

4

Storage methods are not part of the language standard. Old FORTRAN compilers (FORTRAN 77 and earlier) frequently stored all variables statically. The language requires that you use "SAVE" for variables for which the values should be retained across calls to the procedure. But many programmers ignored this requirement and relied on the behavior that all variables retained their values because of the typical design of compilers in the FORTRAN 77 era.

Modern Fortran compilers typically use memory differently and local variables of procedures do not always retain their values if SAVE is omitted. This frequently causes bugs when old programs are compiled with current compilers. Compilers typically provide an option to restore the old behavior. Otherwise it could be a great deal of work to identify all variables in a large legacy program that needed to have the SAVE attribute added to their declaration.

M. S. B.
  • 28,968
  • 2
  • 46
  • 73