He leído su entrada en la referencia del idioma (Intel), pero no puedo entender lo que hace. ¿Podría alguien en términos sencillos explicarme qué significa cuando está incluido en un módulo?fortran GUARDAR declaración
Respuesta
En principio, cuando un módulo sale fuera del alcance, las variables de ese módulo quedan indefinidas, a menos que se declaren con el atributo SAVE o se use una instrucción SAVE. "Indefinido" significa que no puede confiar en la variable que tiene el valor anterior si vuelve a utilizar el módulo; puede tener el valor anterior cuando vuelve a acceder al módulo, o puede que no lo haga; no hay garantía. . Pero muchos compiladores no hacen esto para las variables del módulo - las variables probablemente conservan sus valores - no vale la pena el esfuerzo para el compilador para determinar si un módulo permanece en el alcance o no y, probablemente, se tratan las variables del módulo como variables globales, ¡pero no confíes en eso! Para estar seguro, use "guardar" o "usar" el módulo del programa principal para que nunca se salga del alcance.
"salvar" es también importante en los procedimientos, para almacenar "estado" las invocaciones de la subrutina o función (escrita por @ire_and_curses) - inicializaciones "primera invocación", contadores, etc.
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 = ....
etc.
En este fragmento de código, "contador" informará el número de invocaciones de la subrutina x. Aunque en realidad en Fortran> = 90 uno puede omitir el "guardar" porque la inicialización en la declaración implica "guardar".
En contraste con el caso del módulo, con los compiladores modernos, sin el atributo guardar o la inicialización-en-una-declaración, es normal que las variables locales de procedimientos pierdan sus valores a través de invocaciones. Por lo tanto, si intenta utilizar "var" en una llamada posterior antes de redefinirla en esa llamada, el valor no está definido y probablemente no será el valor calculado en una invocación previa del procedimiento.
Esto es diferente del comportamiento de muchos compiladores de FORTRAN 77, algunos de los cuales conservan los valores de todas las variables locales, aunque esto no fue requerido por el estándar de lenguaje. Algunos programas antiguos se escribieron basándose en este comportamiento no estándar: estos programas fallarán en los compiladores más nuevos. Muchos compiladores tienen la opción de utilizar el comportamiento no estándar y "guardar" todas las variables locales.
de editar posteriormente: actualización con un ejemplo de código que muestra el uso incorrecto de una variable local que debe tener el atributo guardar, pero no:
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
La variable local k de la subrutina es intencionalmente mal uso - en este programa se inicializa en la primera llamada desde control es VERDADERO, pero en la segunda llamada control es FALSO, por lo k no se redefine.Pero sin el atributo guardar k no está definido, por lo que el uso de su valor es ilegal.
Compilar el programa con gfortran, encontré que k conservó su valor de todos modos:
i, j, k= 3 3 3
i, j, k= 4 7 7
Compilar el programa con opciones ifort y optimización agresiva, k pierde su valor:
i, j, k= 3 3 3
i, j, k= 4 7 4
Usando ifort con opciones de depuración, ¡los problemas se detectaron en el tiempo de ejecución!
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
Quizás también valga la pena mencionar que es como la palabra clave "estática" en C. – MasterHD
_ "use" el módulo del programa principal para que nunca salga de scope_, ahora veo la evidencia de por qué no he tenido problemas incluso escribiendo ni siquiera un solo 'SAVE' en mi programa! ¡Gracias! –
Normalmente, las variables locales salen del ámbito de aplicación una vez que la ejecución abandona el procedimiento actual, y por lo tanto no tienen 'memoria' de su valor en las invocaciones previas. SAVE
es una forma de especificar que una variable en un procedimiento debe mantener su valor de una llamada a la siguiente. Es útil cuando desea almacenar estado en un procedimiento, por ejemplo, para mantener un total acumulado o mantener la configuración de una variable.
Hay un good explanation here, con un ejemplo.
Uhmm, ¿podrías dar un ejemplo de eso? Si entiendo correctamente, si declaro SAVE en un módulo, ¿sus variables no pueden cambiar valores en subrutinas? –
@Friedrich Schwartz: No del todo. Aún puede establecer nuevos valores, pero si tuviera que inspeccionar el valor de la variable antes de configurarla, vería el último valor al que había establecido la variable. Sin 'SAVE ', verías' indefinido '. Trabajar a través de un simple ejemplo debería hacerlo más claro. –
Esto como una respuesta a M.S.B. porque la falta de formato en los comentarios probablemente haga un desayuno de cerdo fuera de todo:
En primer lugar, gracias por responder, a los dos. Lo aprecio.
Si entendí bien;
subroutine save(j)
implicit none
integer :: i = 0, j
save i
i = i + j
write(*,*)i
end subroutine save
program test_save
implicit none
integer :: j
j = 1
call save(j)
call save(j)
end program test_save
si no fuera por la declaración GUARDAR en el pequeño ejemplo anterior, la variable i (el valor de la variable) se "perdió" después de la primera llamada de subrutina guardar. Gracias a él, conserva su valor - "1" en este caso, y debido a ello, aumenta a "2" durante la segunda llamada.
¿Lo he acertado? Cerca de tal vez?
Sí, la instrucción SAVE hace que la variable i conserve su valor. Una sutil es que en este ejemplo, en Fortran 90, la declaración de guardado es opcional: "guardar" se aplica automáticamente porque "i" se inicializa en una declaración. La declaración de guardar sería obligatoria en FORTRAN 77. –
Una breve explicación podría ser: el atributo save
dice que el valor de una variable debe conservarse en diferentes llamadas a la misma subrutina/función. De lo contrario, normalmente cuando regresa de una subrutina/función, las variables "locales" pierden sus valores ya que se libera la memoria donde se almacenaron esos valores. Es como static
en C, si conoce este idioma.
- 1. asignación de Fortran de declaración y SAVE atributo Gotcha
- 2. software de conversión para fortran 77 a fortran 90
- 3. ¿Qué significa 10.D00 en Fortran?
- 4. Lectura de la declaración de lectura de Fortran más allá del final de la línea
- 5. comunicado Fortran IF con números/etiquetas en lugar de otra declaración
- 6. Llamando al programa Fortran desde Perl sin guardar los archivos de entrada/salida
- 7. Fortran forall restrictions
- 8. Fortran 90 parámetro tipo
- 9. Función privada en Fortran
- 10. Dormir en Fortran
- 11. Fortran asignar/desasignar
- 12. Fortran 90 Recursos?
- 13. Best Fortran IDE
- 14. ¿Qué significa "%" en Fortran?
- 15. Subrutinas puras en Fortran - Optimización del compilador
- 16. editor con buena compatibilidad fortran
- 17. Administración de memoria Fortran array
- 18. Eclipse con Intel Fortran depurador
- 19. mtrace para un programa fortran
- 20. Llamar código fortran desde C#
- 21. Conversión de FORTRAN a C/C++
- 22. Matrices de cadenas en puentes Fortran-C usando iso_c_binding
- 23. ¿Puede Fortran leer los bytes directamente desde un archivo binario?
- 24. Fortran formato de archivo sin formato
- 25. Cómo imprimir matrices Fortran en GDB?
- 26. salida estándar en el código Fortran MPI
- 27. cómo inicializar matrices bidimensionales de Fortran
- 28. Fortran 90/95 biblioteca para matrices dispersas?
- 29. ¿Es posible imprimir en Fortran en python?
- 30. Función Devolver una matriz en Fortran
Vea también http://stackoverflow.com/questions/2582409/are-local-variables-in-fortran-77-static-or-stack-dynamic/2583248 –
Como complemento a las muy buenas respuestas que obtuvo, mi recomendación es: "nunca use guardar". Es una receta para desastres y hace que la rutina no sea segura y no apátrida. Puede haber razones para usar guardar, pero son muy, muy raros, y puede hacer lo mismo usando un estilo de programación o solución diferente. –