Dopo un lungo e doloroso debug, credo di aver trovato una proprietà unica di Fortran che vorrei verificare qui su StackOverflow.Fortran conserva il valore delle variabili interne tramite chiamate di funzioni e subroutine?
Quello che ho notato è che, per lo meno, il valore delle variabili logiche interne è preservato attraverso chiamate di funzioni o subroutine.
Ecco alcuni esempi di codice per illustrare il mio 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
Questa è l'uscita:
FUNCTION: -9 is negative
SUBROUTINE: -9 is negative
Expected negative.
FUNCTION: 7 is negative
SUBROUTINE: 7 is negative
Expected positive.
Come si può vedere, sembra che una volta che la funzione o subroutine viene chiamato una volta, la variabile logica negative
, se impostata su .TRUE.
, rimane tale nonostante l'inizializzazione di negative
in .FALSE.
nella dichiarazione di dichiarazione del tipo.
Potrei, ovviamente, correggere questo problema aggiungendo semplicemente una riga negativa = .FALSE. dopo aver dichiarato la variabile nella mia funzione e subroutine.
Tuttavia, mi sembra molto strano che ciò sia necessario.
Per motivi di portabilità e riusabilità del codice, il linguaggio (o il compilatore forse) non deve richiedere la reinizializzazione di tutte le variabili interne ogni volta che viene richiamata la subroutine o la funzione?
Credo (per essere sicuro che dovrei andare a controllare lo standard, che non ho con me in questo momento) che a partire dalla F2003, tutte le variabili hanno l'attributo SAVE. – Rook
Sorprendente davvero! – EMiller