Does Fortran preserve the value of internal variables through function and subroutine calls?

To answer your question: Yes Fortran does preserve the value of internal variables through function and subroutine calls.

Under certain conditions ...

If you declare an internal variable with the SAVE attribute it's value is saved from one call to the next. This is, of course, useful in some cases.

However, your question is a common reaction upon first learning about one of Fortran's gotchas: if you initialise an internal variable in its declaration then it automatically acquires the SAVE attribute. You have done exactly that in your subroutines. This is standard-conforming. If you don't want this to happen don't initialise in the declaration.

This is the cause of much surprise and complaint from (some) newcomers to the language. But no matter how hard they complain it's not going to change so you just have to (a) know about it and (b) program in awareness of it.


This isn't too different from static function-scoped variables in C or C++.

Programming language design was in its infancy, back when FORTRAN was developed. If it were being designed from scratch today, no doubt many of the design decisions would have been different.

Originally, FORTRAN didn't even support recursion, there was no dynamic memory allocation, programs played all sorts of type-punning games with COMMON blocks and EQUIVALENCE statements, procedures could have multiple entry points....so the memory model was basically for the compiler/linker to lay out everything, even local variables and numeric literal constants, into fixed storage locations, rather than on the stack. If you wanted, you could even write code that changed the value of "2" to "42"!

By now, there is an awful lot of legacy FORTRAN code out there, and compiler writers go to great lengths to preserve backward-compatible semantics. I can't quote chapter and verse from the standard that mandates the behavior you've noted, nor its rationale, but it seems reasonable that backward compatibility trumped modern language design sensibilities, in this instance.


This has been discussed several times here, most recently at Fortran assignment on declaration and SAVE attribute gotcha

You don't have to discover this behavior by experimentation, it is clearly stated in the better textbooks.

Different languages are different and have different behaviors.

There is a historical reason for this behavior. Many compilers for Fortran 77 and earlier preserved the values of ALL local variables across calls of procedures. Programmers weren't supposed to rely upon this behavior but many did. According to the standard, if you wanted a local variable (non-COMMON) to retain its value you needed to use "SAVE". But many programmers ignored this. In that era programs were less frequently ported to different platforms and compilers, so incorrect assumptions might never be noticed. It is common to find this problem in legacy programs -- current Fortran compilers typically provide a compiler switch to cause all variables to be saved. It would be silly for the language standard to require that all local variables retain their values. But an intermediate requirement that would rescue many programs that were careless with "SAVE" would be to require all variables initialized in their declarations to automatically have the SAVE attribute. Hence what you discovered....