Fortran DISCUSSION

Why does a local variable initialised in its declaration keep its value between calls in Fortran?

Started by ajinkyakhaladkar Fortran save attributeimplicit savevariable initialisationstatic local variablesOpenMP race
4 replies 248 views 5 participants
Latest activity · 30 Sep 2026

Why does a local variable initialised in its declaration keep its value between calls in Fortran?

ajinkyakhaladkar Fortran Forum
#1

I wrote a function that counts valid samples in an array. It declares integer :: count = 0, loops over the data and returns count. The first call returns 3 as expected, but calling it again with the same array returns 6, then 9.

In C the same line would reset the variable on every call. What is Fortran doing here, is this related to the save attribute I see in older code, and how should a local variable be initialised on each call?

Community replies 4

Re: Why does a local variable initialised in its declaration keep its value between calls in Fortran?

#2

In Fortran an initialisation in a declaration is not an assignment executed on entry. It sets the variable's value once, before the program starts, and it implicitly gives the variable the save attribute. integer :: count = 0 therefore means exactly integer, save :: count = 0: a static variable that keeps its value from one call to the next. That is why you see 3, 6, 9.

To get a fresh value per call, declare and assign separately: integer :: count, then count = 0 as the first executable statement.

Re: Why does a local variable initialised in its declaration keep its value between calls in Fortran?

#3

save is the explicit way to ask for that persistence, for example for a call counter or a flag that records that a table has been built: logical, save :: first = .true.. A bare save statement with no list saves every local variable in the scoping unit. The data statement has the same implicit-save effect as a declaration initialiser, which is where much of the older code gets it from.

A local without save formally becomes undefined when the procedure returns. It may appear to keep its value with a particular compiler, but that is not something to rely on.

Re: Why does a local variable initialised in its declaration keep its value between calls in Fortran?

#4

That last point explains a lot of legacy behaviour. Many old compilers allocated all locals statically, and programs quietly came to depend on values surviving between calls. Modern compilers put most locals on the stack, so such code breaks when it is recompiled.

Options such as -fno-automatic in gfortran or -save in the Intel compiler restore the old behaviour for a whole file as a stopgap, but the durable fix is to find the variables that really need to persist and mark those save explicitly. Compiling with warnings for uninitialised variables, and with an option that fills locals with invalid values (gfortran has -finit-real=snan), helps locate them.

Re: Why does a local variable initialised in its declaration keep its value between calls in Fortran?

#5

Saved variables are shared state, which matters as soon as the procedure is recursive or called from several threads. With OpenMP, every thread entering the routine reads and writes the same count, giving a data race and totals that change from run to run. An unintended implicit save is a classic source of bugs that only appear when a loop is parallelised.

The same rule covers pointers: real, pointer :: p => null() in a declaration also makes p saved. If you want derived-type objects to start clean on every call, give the type default component initialisation, for example integer :: n = 0 inside the type definition; that is applied each time a local object of the type is created and does not imply save.

TEP COMMUNITY