Ho letto la sua voce nella lingua di riferimento (Intel), ma non riesco a capire cosa faccia. Qualcuno potrebbe, in parole povere, spiegarmelo, cosa significa quando è incluso in un modulo?fortran SAVE statement
risposta
In principio quando un modulo diventa fuori campo, le variabili di quel modulo diventano indefinite - a meno che non siano dichiarate con l'attributo SAVE, o venga utilizzata un'istruzione SAVE. "Non definito" significa che non ti è permesso fare affidamento sulla variabile che ha il valore precedente se usi di nuovo il modulo - potrebbe avere il valore precedente quando riaccedi al modulo, o potrebbe non farlo - non c'è garanzia . Ma molti compilatori non lo fanno per il modulo variabili - le variabili probabilmente mantengono i loro valori - non vale la pena per il compilatore di capire se un modulo rimane nell'ambito o meno e probabilmente le variabili del modulo sono trattate come variabili globali - ma non fare affidamento su questo! Per sicurezza, usa "salva" o "usa" il modulo dal programma principale in modo che non diventi mai fuori portata.
"salvare" è importante anche nelle procedure, per memorizzare "stato" attraverso invocazioni della subroutine o di una funzione (come scritto da @ire_and_curses) - inizializzazione "prima invocazione", contatori, ecc
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 = ....
ecc.
In questo frammento di codice, "contatore" riporterà il numero di invocazioni della subroutine x. Sebbene in realtà in Fortran> = 90 si può omettere il "salvataggio" perché l'inizializzazione nella dichiarazione implica "salva".
In contrasto con il caso del modulo, con i compilatori moderni, senza l'attributo di salvataggio o l'inizializzazione su una dichiarazione, è normale che le variabili locali delle procedure perda i loro valori attraverso invocazioni. Pertanto, se si tenta di utilizzare "var" in una chiamata successiva prima di ridefinirla in tale chiamata, il valore non è definito e probabilmente non sarà il valore calcolato su una precedente chiamata della procedura.
Questo è diverso dal comportamento di molti compilatori FORTRAN 77, alcuni dei quali mantenevano i valori di tutte le variabili locali, anche se questo non era richiesto dallo standard di lingua. Alcuni vecchi programmi sono stati scritti facendo affidamento su questo comportamento non standard - questi programmi non funzioneranno con i nuovi compilatori. Molti compilatori hanno un'opzione per usare il comportamento non standard e "salvare" tutte le variabili locali.
Successivamente modificare: aggiornamento con un esempio di codice che mostra corretto utilizzo di una variabile locale che dovrebbe avere l'attributo salvataggio ma non:
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
variabile locale k della subroutine è volutamente abusato - in questo programma è inizializzato nella prima chiamata dal il controllo è VERO, ma sulla seconda chiamata il controllo è FALSE, quindi k non viene ridefinito.Ma senza l'attributo di salvataggio k non è definito, quindi l'utilizzo del suo valore è illegale.
Compilare il programma con gfortran, ho scoperto che k mantenuto il suo valore in ogni caso:
i, j, k= 3 3 3
i, j, k= 4 7 7
Compilare il programma con le opzioni ifort e ottimizzazione aggressiva, k ha perso il suo valore:
i, j, k= 3 3 3
i, j, k= 4 7 4
Usando ifort con le opzioni di debug, i problemi sono stati rilevati in fase di esecuzione!
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
Forse vale la pena ricordare che è come la parola chiave "statica" in C. – MasterHD
_ "usa" il modulo dal programma principale in modo che non vada mai fuori portata_, ora vedo l'ovvietà nel motivo per cui non ho avuto problemi nemmeno a scrivere nemmeno un singolo 'SAVE' nel mio programma! Grazie! –
Normalmente, le variabili locali escono dall'ambito di applicazione una volta che l'esecuzione ha abbandonato la procedura corrente e quindi non ha memoria del loro valore nelle chiamate precedenti. SAVE
è un modo per specificare che una variabile in una procedura deve mantenere il suo valore da una chiamata alla successiva. È utile quando si desidera memorizzare lo stato in una procedura, ad esempio per mantenere un totale parziale o mantenere la configurazione di una variabile.
C'è un good explanation here, con un esempio.
Uhmm, potresti fare un esempio? Se ho capito bene, se dichiaro SALVA in un modulo, le sue variabili non possono cambiare i valori nelle subroutine? –
@Friedrich Schwartz: Non proprio. Puoi ancora impostare nuovi valori, ma se dovessi controllare il valore della variabile prima di impostarla, vedresti l'ultimo valore a cui hai impostato la variabile. Senza 'SAVE', vedresti 'indefinito'. Lavorare attraverso un semplice esempio dovrebbe renderlo più chiaro. –
Pubblicare come risposta a M.S.B. perché la mancanza di formattazione nei commenti sarebbe probabilmente fare colazione di maiale fuori dal tutto:
Innanzitutto, grazie per aver risposto, entrambi. Lo apprezzo.
Se ho capito bene;
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
Se non fosse per l'istruzione SAVE nel piccolo esempio di cui sopra, la variabile i (il valore della variabile) sarebbe "perso" dopo la prima chiamata di salvare subroutine. Grazie ad esso, mantiene il suo valore - "1" in questo caso, e per questo aumenta a "2" durante la seconda chiamata.
Ho capito bene? Vicino forse?
Sì, l'istruzione SAVE fa sì che la variabile i mantenga il suo valore. Uno di questi è che in questo esempio, in Fortran 90, l'istruzione save è facoltativa: "save" si applica automaticamente perché "i" è inizializzato in una dichiarazione. La dichiarazione di salvataggio sarebbe obbligatoria in FORTRAN 77. –
Una breve spiegazione potrebbe essere: l'attributo save
dice che il valore di una variabile deve essere conservato tra diverse chiamate alla stessa subroutine/funzione. Altrimenti normalmente quando si ritorna da una subroutine/funzione, le variabili "locali" perdono i loro valori poiché la memoria in cui sono stati memorizzati quei vars è stata rilasciata. È come static
in C, se conosci questa lingua.
- 1. assegnazione Fortran sulla dichiarazione e SAVE attributo Gotcha
- 2. SQL - CASE STATEMENT - WHEN statement AND statement
- 3. Differenza tra `--save` e` --save-dev`
- 4. Quando usare `save` vs` save! `Nel modello?
- 5. Doctrine date in save override/before save
- 6. statement statement con due variabili alla volta
- 7. Errore: dichiarazione inclassificabile in FORTRAN
- 8. FORTRAN READ()
- 9. FORTRAN WRITE()
- 10. Funzioni FORTRAN
- 11. Fortran DEALLOCATE
- 12. NHibernate Cascade = save-update "
- 13. PHPExcel save file
- 14. PDFsharp save to MemoryStream
- 15. django foreign key save
- 16. VIM: RSync on save
- 17. Phalcon save not working
- 18. .save mangusta() non funziona
- 19. Spark ML - Save OneVsRestModel
- 20. CallableStatement vs Statement
- 21. If statement in C++
- 22. while else statement? PHP
- 23. Jinja2 If Statement
- 24. if statement intero
- 25. DBNull if statement
- 26. SQlite concat select statement
- 27. DB2 CASE Statement
- 28. C# lock statement performance
- 29. Need Help- Switch statement
- 30. PHP PDO + Prepare Statement
Vedere anche http://stackoverflow.com/questions/2582409/are-local-variables-in-fortran-77-static-or-stack-dynamic/2583248 –
Come complemento alle ottime risposte che hai ottenuto, la mia raccomandazione è: "non usare mai salvare". È una ricetta per il disastro e rende la routine non thread safe e non apolidi. Ci possono essere motivi per usare save, ma sono molto, molto rari, e puoi fare lo stesso usando uno stile di programmazione o una soluzione diversa. –