In this issue, Dr. Fortran takes on another less-understood feature of the Fortran language, the SAVE attribute.
Back in the “good old days” of Fortran programming, when lowercase letters hadn’t been invented yet and we strung our core memory wires by hand, programmers knew that local variables lived in fixed memory locations and, of course, took advantage of that, writing code such as this:
SUBROUTINE SUB INTEGER I I = I + 1 WRITE (6,*) 'New I=',I END
The idea was that the value of the local variable I was preserved between calls to routine SUB, so that subsequent calls would get successive values of I. (Many of these same programmers assumed that variables were zero-initialized as well.) However, the Fortran language didn’t make such promises and, with the advent of improved optimization and “split lifetime analysis” which could make variables live in registers or on the stack, programs which made such assumptions could break.
To accommodate the useful notion of a local variable whose definition status is preserved across routine calls, Fortran 77 added the SAVE statement. If a local variable (not a dummy argument) was named in a SAVE statement, its value at the point of the RETURN or END statement was preserved to the next call to that subroutine or function. Named COMMON blocks could also be SAVEd, but didn’t need to be if there was always a routine active in the call tree which used that COMMON. Blank COMMON was implicitly SAVEd. An interesting tidbit is that in Fortran 77, a DATA-initialized variable’s value was preserved without needing SAVE as long as you didn’t redefine the variable. Fortran 90 removed that last clause for local variables, so that an “initially defined” local variable is implicitly SAVEd, but the catch about redefinition still applies to variables in named COMMON blocks.
One common misconception is that SAVE implies static (fixed address) allocation for a variable. This is not so – in fact, if the compiler can determine that a SAVEd variable is always defined before use, then it could decide to make that variable live in a non-static (register or stack) location. The Fortran standard has no mechanism for saying “static and I mean it” – even the Compaq Fortran STATIC extension doesn’t do this. Right now, the best way to ensure that a variable is allocated statically is to put it in COMMON and give it the VOLATILE attribute (VOLATILE is an extension [but is standard in F2003 – ed.]).
Fortran 90 added a new twist to this – ALLOCATABLE arrays. Fortran 90 implied, and Fortran 95 makes clear, that local ALLOCATABLE variables get automatically deallocated and become undefined when the routine in which they are declared is returned from. This has been a big shock to some programmers who figured that the values would stay around. If you want the array to remain there, use SAVE.
Given that many programs assumed SAVE semantics for variables, most vendors, including DIGITAL, had their Fortran 77 compilers give implicit SAVE semantics to variables which were used before being defined. (Note that this doesn’t apply to ALLOCATABLE variables.) [Intel Fortran does NOT give SAVE semantics by default.] So why use SAVE? First, it is a lways a good idea to tell the compiler what you want, rather than making assumptions based on a current implementation. Compilers keep getting smarter and what “works” today might not work next year. Proper use of SAVE can also aid with error reporting – some compilers will suppress “use before defined” warnings for variables with an explicit SAVE attribute. It’s also good to let the human who reads your code know that you are assuming the variable’s value is preserved. That’s why Dr. Fortran says, “Better SAVE than sorry!”
(From Intel Developer Zone, copied with permission)