время жизни переменных и статических массивов в Фортране - PullRequest
1 голос
/ 12 апреля 2019

Я слышал, что в Fortran77 все локальные переменные в функции создаются в начале выполнения основной программы и существуют в течение всего времени выполнения, а не создаются при входе в функцию и уничтожаются при выходе. Я не знаю, так ли это до сих пор в более новом Fortran. Есть ли способ, который может проверить это? Один из полезных тестов - проверить, сохраняют ли переменные свои значения между вызовами. Вот простой тест:

  program main
  call p()
  call p()
  call p()
 end program main

 subroutine p()
  real :: a(3)
  a=a+1
  write(*,*) a(1), a(2), a(3)
 end subroutine p

Мой тест с использованием gfortran указывает, что массив a сохраняет свои значения между вызовами, то же поведение, что и используемый атрибут save. Мне интересно, является ли это стандартом в языке Фортран или зависит от реализации компилятора.

Ответы [ 2 ]

2 голосов
/ 13 апреля 2019

Ради интереса, мы можем попробовать программу, в которой между последовательными вызовами p():

может вызываться какая-то другая подпрограмма (например, foo()).
program main
    call p()
    !  call foo()  ! (*)
    call p()
    !  call foo()  ! (*)
    call p()
end

subroutine p()
    real :: a(3)
    a = a + 1
    write(*,*) "a = ", a
end

subroutine foo()
    real :: b(3)
    b = b * 10
    write(*,*) "b = ", b
end

С комментариями строк (*) мы получаем

 ! gfortran-8.2
 a =    1.00000000       4.74066630E+21   1.00000000    
 a =    2.00000000       4.74066630E+21   2.00000000    
 a =    3.00000000       4.74066630E+21   3.00000000

 ! PGI18.10
 a =     1.000000        1.000000        1.000000    
 a =     2.000000        2.000000        2.000000    
 a =     3.000000        3.000000        3.000000    

пока строки (*) не закомментированы, мы получим

 ! gfortran-8.2
 a =    1.00000000       4.74066630E+21   1.00000000    
 b =    10.0000000       4.74066641E+22   10.0000000    
 a =    11.0000000       4.74066641E+22   11.0000000    
 b =    110.000000       4.74066623E+23   110.000000    
 a =    111.000000       4.74066623E+23   111.000000

 ! PGI18.10
 a =     1.000000        1.000000        1.000000    
 b =     0.000000        0.000000        0.000000    
 a =     2.000000        2.000000        2.000000    
 b =     0.000000        0.000000        0.000000    
 a =     3.000000        3.000000        3.000000  

(Это всего лишь эксперимент / иллюстрация поведения локальных переменных (т.е. не обязательно «СОХРАНЕНО», как это может показаться в более простом случае), и, пожалуйста, см. другой ответ и комментарии для подробных объяснений.)

2 голосов
/ 12 апреля 2019

Такой тест не может ничего доказать. Тот факт, что в стеке между двумя вызовами функций остается некоторое количество мусора, может быть простым совпадением.

Локальные переменные функции действительны только во время вызова функции, в которой было определено их значение. Это также верно в Фортране 77. Если значение следует сохранить, переменные должны быть объявлены SAVE.

...