HP Fortran Programmer Guide (766160-001, March 2014)

HP Fortran allocates static storage for the following variables:
Variables specified in a COMMON or EQUIVALENCE statement.
Variables initialized in a type declaration statement or in a DATA statement.
Variables specified in a SAVE or STATIC statement. A SAVE statement without a variable list
specifies static storage for all variables in the scoping unit.
Variables in program files that have been compiled with the +saveor
+Oinitcheckcommand-line option. See “Uninitialized variables” (page 144)for information
about using these options when porting.
Static variables have two characteristics that are of special interest:
They are set to 0 or null value at load-time.
They do not require re-initialization at each invocation of their program unit.
Static variables have several disadvantages. In Fortran programs that use recursion, static variables
can defeat one purpose of recursion—to provide a fresh set of local variables at each recursive
call. Also, the widespread use of static variables in a program can slow its performance: static
variables are ineligible for such fundamental optimizations as register allocation, and they can
limit the optimization of program units that use them.
The following example program illustrates the difference between automatic and static variables.
The program consists of a main program unit that calls a recursive internal subroutine. The subroutine
increments two variables (stat_val and auto_val), prints the updated variables, and then calls itself
recursively. Neither of the two variables is explicitly initialized, but stat_val is declared with the
SAVE attribute, which means that it is allocated static storage and is pre-initialized to 0 by the
compiler.
Example 3-1 recursive.f90
PROGRAM main
! This program calls a recursive internal subroutine.
CALL recurse
CONTAINS
! This subroutine calls itself four times.
! Each time it is called, it adds 1 to the values in
! stat_val and auto_val and displays the result.
! stat_val has the SAVE attribute and therefore is
! pre-initialized and retains its value between calls.
! auto_val is an automatic variable and therefore has
! an unpredictable value (plus 1) at each call.
RECURSIVE SUBROUTINE recurse
INTEGER(KIND=1), SAVE :: stat_val
INTEGER(KIND=1) :: auto_val
stat_val = stat_val + 1
auto_val = auto_val + 1
PRINT *, stat_val = , stat_val
PRINT *, auto_val = , auto_val
IF (stat_val < 4) THEN
CALL recurse()
END IF
END SUBROUTINE recurse
END PROGRAM main
Following are the command lines to compile and execute this program, along with sample output.
Notice that stat_val regularly increments at each call. The reason is that it is a static variable and
therefore retains its value between calls. But auto_val is not actually incremented; it is an automatic
variable and is given a fresh (and uninitialized) memory location at each call. In other words, the
subroutine adds 1 to whatever value happened to be in the memory location that was allocated
to auto_val at the start of the call:
$ f90 recursive.f90
$ a.out
68 Controlling data storage