I’d say save
is the opposite of “going out of scope”. It’s telling the compiler to preserve the value “alive” between function calls. It’s essentially part of the global state, but only visible internally within the procedure. Here’s the general concept: Static variable - Wikipedia
If it helps, you can imagine save
as a static
variable within a function in C:
// count.c
#include <stdio.h>
void count(int *value)
{
static int counter_ = 0;
counter_++;
if (value) *value = counter_;
}
#define nil (void *) 0
int main() {
count(nil);
count(nil);
count(nil);
int value;
count(&value);
printf("counter = %d\n", value);
return 0;
}
}
! count.f90
program main
implicit none
integer :: value
call count()
call count()
call count()
call count(value)
print *, "count = ", value
contains
subroutine count(value)
integer, intent(out), optional :: value
integer, save :: counter_ = 0
counter_ = counter_ + 1
if (present(value)) value = counter_
end subroutine
end program
If you don’t want save anymore, e.g. to make the library thread-safe, or other reasons, the right approach would be to encapsulate the save
’d variables into a derived type/struct, which is passed between calls.
type :: dgetv0_state
logical :: first, inits, orth
integer :: idist, iseed(4), iter, msglvl, jj
double precision :: rnorm0
end type
subroutine dgetv0
& ( ido, bmat, itry, initv, n, j, v, ldv, resid, rnorm,
& ipntr, workd, ierr, state )
C ^-- extra dummy argument
C ...
type(dgetv0_state), intent(inout) :: state
The caller would be expected to keep the values in state
intact without modification.