Dois-je mettre implicit none
dans chaque fonction et sous-programme?
Ou suffit-il de le placer au début du module contenant ces fonctions et sous-routines?
Ou est-ce suffisant de le mettre au début du programme qui utilise ces modules?
D'après l'observation du code de travail des autres, implicit none
est inclus dans tous ces endroits. Je ne sais pas si cela se fait de manière redondante car la suppression de implicit none
à partir de sous-programmes toujours compilés et produit la même sortie.
Au fait, j'utilise gfortran fortran 90
.
L'instruction implicit
(y compris implicit none
) s'applique à une unité de portée. Une telle chose est définie comme
Construction BLOCK, définition de type dérivé, corps d'interface, unité de programme ou sous-programme, excluant toutes les unités de portée imbriquées
Cette "exclusion de toutes les unités de portée imbriquées" suggère qu'il peut être nécessaire/souhaitable d'avoir implicit none
dans chaque fonction et sous-routine (collectivement, procédures) définies dans un module. Cependant, à l'intérieur des procédures contenues dans un module, il existe un mappage par défaut basé sur l'unité de portée Host. Donc avec implicit none
dans le module, il n'est pas nécessaire de l'avoir dans les procédures contenues.
Cette règle d'unité de portée d'hôte s'applique également aux programmes internes. Cela signifie que implicit none
dans le programme principal couvre toutes les procédures qu'il contient; et qu'il en va de même pour les programmes internes de procédures de module. Les constructions de blocs le voient également, et l'instruction implicit
n'est même pas autorisée dans l'une d'entre elles.
Cependant, les fonctions/sous-programmes externes n'hériteront pas du comportement implicite d'un programme ou d'un module, et les modules ne l'hériteront pas des programmes/autres modules qui use
les. Cela a clairement un sens car le typage implicite doit être connu au moment de la compilation et être bien défini quelle que soit son utilisation finale.
De plus, on ne peut pas faire
implicit none
use somemodule
end program
Une instruction implicit
doit suivre toutes les instructions use
.
Cette règle d'unité de portée d'hôte ne s'applique notamment pas aux corps d'interface. réponse de IanH motive cette exception, mais c'est une chose suffisamment importante pour souligner à nouveau. Cela a causé beaucoup de confusion.
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
Concernant le test de suppression de implicit none
à partir d'un sous-programme: si le code est valide avec implicit none
alors il doit être valide et identique sans cette déclaration. Toutes les entités doivent être explicitement déclarées dans le premier cas, donc aucune règle implicite ne serait appliquée dans le second.
Non, oui (en quelque sorte) et non.
Une fois par unité de programme (ce qui n'est pas la même chose qu'une fois par programme) et dans chaque corps d'interface est suffisant.
Une unité de programme est soit un programme principal, un module, un sous-programme externe (une fonction ou un sous-programme de sous-programme qui n'apparaît pas après l'instruction CONTAINS d'un autre type d'unité de programme), une unité de programme de données de bloc ou un sous-module. Sauf indication contraire avec une instruction IMPLICIT, la valeur par défaut dans chaque unité de programme est le mappage par défaut des choses commençant par I-N comme entier par défaut et tout le reste comme réel par défaut.
Le même principe s'applique aux corps d'interface - car ils sont censés être un instantané de la partie spécification d'une procédure définie dans une autre unité de programme. Cette autre unité de programme aurait le mappage par défaut, sauf indication contraire, de sorte que le corps de l'interface a le mappage par défaut, sauf indication contraire.
À l'intérieur d'une unité de programme, les sous-programmes internes ou les sous-programmes de module héritent du typage implicite spécifié dans leur hôte, en l'absence d'une instruction IMPLICIT "locale" dans le sous-programme proprement dit.
La spécification redondante d'IMPLICIT NONE est inoffensive. Vous le voyez souvent où des sous-programmes qui étaient auparavant des sous-programmes externes ont été placés dans un module.
Voici une réponse informelle basée sur ce qui fonctionne pour moi.
Mon code Fortran est dans deux types de fichiers - ceux contenant un programme principal et ceux contenant un seul module. Dans chaque type de fichier, IMPLICIT NONE apparaît juste après les instructions "program foo" ou "module foo" et après les instructions USE en haut. Il n'apparaît pas dans les sous-programmes ou les fonctions, car cela serait redondant.
Si vous utilisez gfortran
, vous pouvez aussi simplement ajouter un -fimplicit-none
paramètre.
Notez qu'il s'agit d'une solution spécifique au compilateur. D'autres compilateurs répandus peuvent ne pas prendre en charge ce paramètre. Par exemple, le ifort
d'Intel ignore cela comme une option inconnue.