Después de mucha depuración dolorosa, creo que he encontrado una propiedad única de Fortran que me gustaría verificar aquí en stackoverflow.¿Fortran conserva el valor de las variables internas a través de llamadas de función y subrutina?
Lo que he notado es que, al menos, el valor de las variables lógicas internas se conserva a través de llamadas a funciones o subrutinas.
Aquí es un código de ejemplo para ilustrar mi punto:
PROGRAM function_variable_preserve
IMPLICIT NONE
CHARACTER(len=8) :: func_negative_or_not ! Declares function name
INTEGER :: input
CHARACTER(len=8) :: output
input = -9
output = func_negative_or_not(input)
WRITE(*,10) input, " is ", output
10 FORMAT("FUNCTION: ", I2, 2A)
CALL sub_negative_or_not(input, output)
WRITE(*,20) input, " is ", output
20 FORMAT("SUBROUTINE: ", I2, 2A)
WRITE(*,*) 'Expected negative.'
input = 7
output = func_negative_or_not(output)
WRITE(*,10) input, " is ", output
CALL sub_negative_or_not(input, output)
WRITE(*,20) input, " is ", output
WRITE(*,*) 'Expected positive.'
END PROGRAM function_variable_preserve
CHARACTER(len=*) FUNCTION func_negative_or_not(input)
IMPLICIT NONE
INTEGER, INTENT(IN) :: input
LOGICAL :: negative = .FALSE.
IF (input < 0) THEN
negative = .TRUE.
END IF
IF (negative) THEN
func_negative_or_not = 'negative'
ELSE
func_negative_or_not = 'positive'
END IF
END FUNCTION func_negative_or_not
SUBROUTINE sub_negative_or_not(input, output)
IMPLICIT NONE
INTEGER, INTENT(IN) :: input
CHARACTER(len=*), INTENT(OUT) :: output
LOGICAL :: negative = .FALSE.
IF (input < 0) THEN
negative = .TRUE.
END IF
IF (negative) THEN
output = 'negative'
ELSE
output = 'positive'
END IF
END SUBROUTINE sub_negative_or_not
Ésta es la salida:
FUNCTION: -9 is negative
SUBROUTINE: -9 is negative
Expected negative.
FUNCTION: 7 is negative
SUBROUTINE: 7 is negative
Expected positive.
Como se puede ver, parece que una vez que la función o subrutina se llama una vez, la variable lógica negative
, si se cambia a .TRUE.
, permanece como tal a pesar de la inicialización de negative
a .FALSE.
en la declaración de declaración de tipo.
Podría, por supuesto, corregir este problema simplemente agregando una línea negativa = .FALSE. después de declarar la variable en mi función y subrutina.
Sin embargo, me parece muy extraño que sea necesario.
Por razones de portabilidad y reutilización del código, ¿no debería el lenguaje (o el compilador quizás) requerir la reinicialización de todas las variables internas cada vez que se llama a la subrutina o función?
Creo (para asegurarme de que tendría que verificar el Estándar, que no tengo ahora mismo) que a partir de F2003, todas las variables tienen el atributo SAVE. – Rook
¡Sorprendente! – EMiller