В принципе, когда модуль выходит из области видимости, переменные этого модуля становятся неопределенными - если они не объявлены с атрибутом SAVE или не используется инструкция SAVE. «Не определено» означает, что вы не можете полагаться на переменную, имеющую предыдущее значение, если вы снова используете модуль - он может иметь прежнее значение при повторном доступе к модулю, или он может не иметь - нет гарантии , Но многие компиляторы не делают этого для module переменных - переменные, вероятно, сохраняют свои значения - компилятору не стоит пытаться выяснить, остается ли модуль в области действия или нет, и, вероятно, переменные модуля рассматриваются как глобальные переменные - но не полагайтесь на это! Для безопасности либо используйте «сохранить», либо «используйте» модуль из основной программы, чтобы он никогда не выходил за рамки.
«save» также важно в процедурах, чтобы сохранить «состояние» между вызовами подпрограммы или функции (как написано @ire_and_curses) - инициализация «первого вызова», счетчики и т. Д.
subroutine my_sub (y)
integer :: var
integer, save :: counter = 0
logical, save :: FirstCall = .TRUE.
counter = counter + 1
write (*, *) counter
if (FirstCall) then
FirstCall = .FALSE.
....
end if
var = ....
и т.д.
В этом фрагменте кода "counter" сообщит количество вызовов подпрограммы x. Хотя на самом деле в Fortran> = 90 можно пропустить «save», потому что инициализация в объявлении подразумевает «save».
В отличие от случая модуля, в современных компиляторах без атрибута save или объявления инициализации по объявлению локальные переменные процедур обычно теряют свои значения при вызовах. Поэтому, если вы попытаетесь использовать «var» в последующем вызове, прежде чем переопределять его в этом вызове, значение будет неопределенным и, вероятно, не будет значением, рассчитанным для предыдущего вызова процедуры.
Это отличается от поведения многих компиляторов FORTRAN 77, некоторые из которых сохранили значения всех локальных переменных, даже если это не требовалось языковым стандартом. Некоторые старые программы были написаны с учетом этого нестандартного поведения - эти программы не будут работать на новых компиляторах. Многие компиляторы имеют возможность использовать нестандартное поведение и «сохранять» все локальные переменные.
ПОСЛЕДНЕЕ РЕДАКТИРОВАНИЕ: обновление с примером кода, который показывает неверное использование локальной переменной, которая должна иметь атрибут сохранения, но не:
module subs
contains
subroutine asub (i, control)
implicit none
integer, intent (in) :: i
logical, intent (in) :: control
integer, save :: j = 0
integer :: k
j = j + i
if ( control ) k = 0
k = k + i
write (*, *) 'i, j, k=', i, j, k
end subroutine asub
end module subs
program test_saves
use subs
implicit none
call asub ( 3, .TRUE. )
call asub ( 4, .FALSE. )
end program test_saves
Локальная переменная k подпрограммы преднамеренно используется неправильно - в этой программе она инициализируется при первом вызове, поскольку control имеет значение TRUE, но при втором вызове control - ЛОЖЬ, поэтому k не переопределено. Но без атрибута save k не определено, поэтому использование его значения недопустимо.
Скомпилировав программу с помощью gfortran, я обнаружил, что k все равно сохраняет свое значение:
i, j, k= 3 3 3
i, j, k= 4 7 7
Скомпилировав программу с ifort и агрессивными параметрами оптимизации, k потерял свое значение:
i, j, k= 3 3 3
i, j, k= 4 7 4
При использовании ifort с параметрами отладки проблемы были обнаружены во время выполнения!
i, j, k= 3 3 3
forrtl: severe (193): Run-Time Check Failure. The variable 'subs_mp_asub_$K' is being used without being defined