Dove mettere “implicito nessuno” in Fortran

Devo mettere implicit none in ogni funzione e subroutine?

O è sufficiente metterlo all’inizio del modulo che contiene queste funzioni e subroutine?

O è sufficiente metterlo all’inizio del programma che utilizza questi moduli?

Dall’osservazione del codice di lavoro altrui, implicit none è incluso in tutti questi luoghi. Non sono sicuro che ciò avvenga in modo ridondante perché la rimozione di implicit none codice implicit none dalle subroutine è ancora compilata e ha prodotto lo stesso risultato.

A proposito, sto usando gfortran fortran 90 .

L’istruzione implicit (incluso implicit none ) si applica a un’unità di scoping . Una cosa del genere è definita come

Costruisci BLOCK, definizione del tipo derivato, corpo dell’interfaccia, unità di programma o sottoprogramma, escludendo tutte le unità di ambito annidate in esso

Questo “escludendo tutte le unità di scope annidate in esso” suggerisce che potrebbe essere necessario / desiderabile avere implicit none in ogni funzione e subroutine (collettivamente, procedure) definite in un modulo. Tuttavia, all’interno delle procedure contenute all’interno di un modulo è presente un mapping predefinito basato sull’unità di scoping dell’host . Quindi, con implicit none nel modulo, non è necessario averlo nelle procedure contenute.

Questa regola dell’unità di scoping dell’host si applica ugualmente ai programmi interni. Ciò significa che implicit none nel programma principale copre tutte le procedure in esso contenute; e che lo stesso vale per i programmi interni delle procedure di modulo. I costrutti a blocchi lo vedono anche, e l’affermazione implicit non è nemmeno ammessa all’interno di uno di questi.

Tuttavia, le funzioni esterne / subroutine non erediteranno il comportamento implicito da un programma o un modulo e i moduli non erediteranno da programmi / altri moduli che li use . Ciò ha chiaramente senso poiché la tipizzazione implicita deve essere nota al momento della compilazione ed essere ben definita, indipendentemente dal loro uso finale.

Inoltre, non si può fare

 implicit none use somemodule end program 

Una dichiarazione implicit deve seguire tutte le dichiarazioni di use .

Questa regola dell’unità di scoping dell’host, in particolare, non si applica ai corpi dell’interfaccia. La risposta di IanH motiva quell’eccezione , ma è una cosa abbastanza importante da ri-sottolineare. Ha causato molta confusione.

 module mod implicit none interface subroutine external_sub() ! The default implicit typing rules apply here unless there is an implicit ! statement, such as implicit none. Those from the module aren't in force here. end subroutine end interface end module 

Per quanto riguarda il test di rimozione di implicit none da una subroutine: se il codice è valido con implicit none allora deve essere valido e identico senza quella dichiarazione. Tutte le entity framework devono essere esplicitamente dichiarate nel primo caso, quindi non verranno applicate regole implicite nel secondo caso.

No, Sì (sorta di) e No.

Una volta per unità di programma (che non è la stessa cosa di una volta per programma) e in ogni corpo di interfaccia è sufficiente.

Un’unità di programma è un programma principale, un modulo, un sottoprogramma esterno (una funzione o un sottoprogramma di subroutine che non appare dopo l’istruzione CONTAINS di un altro tipo di unità di programma), un’unità di programma di dati di blocco o un sottomodulo. Salvo diversamente specificato con una dichiarazione IMPLICIT, il valore predefinito in ogni unità di programma è la mapping predefinita di cose che iniziano con IN come intero predefinito e tutto il resto come predefinito reale.

Lo stesso principio vale per i corpi di interfaccia, in quanto dovrebbero essere un’istantanea della parte specifica di una procedura definita in un’altra unità di programma. Quella altra unità di programma avrebbe la mapping di default se non diversamente specificato diversamente, quindi il corpo dell’interfaccia ha la mapping predefinita se non diversamente specificato diversamente.

All’interno di un’unità di programma, sottoprogrammi interni o sottoprogrammi di moduli ereditano qualsiasi tipo di digitazione implicita specificata nel loro ospite, in assenza di un’istruzione IMPLICIT “locale” all’interno del sottoprogramma corretto.

Le specifiche ridondanti di IMPLICIT NONE sono innocue. Lo vedi spesso dove i sottoprogrammi che erano precedentemente sottoprogrammi esterni sono stati inseriti in un modulo.

Ecco una risposta informale basata su ciò che funziona per me.

Il mio codice Fortran è in due tipi di file: quelli che contengono un programma principale e quelli che contengono un singolo modulo. In ogni tipo di file, IMPLICIT NONE appare subito dopo le istruzioni “program foo” o “module foo” e dopo le istruzioni USE in alto. Non appare all’interno di subroutine o funzioni, perché sarebbe ridondante.

Se stai usando gfortran , puoi semplicemente aggiungere un parametro -fimplicit-none .

Si noti che questa è una soluzione specifica per il compilatore. Altri compilatori diffusi potrebbero non supportare questo parametro. Ad esempio, ifort di Intel lo ignora come opzione sconosciuta.