Les bonnes pratiques dictent que les arguments des sous-programmes dans Fortran doivent chacun avoir une intention spécifiée (c'est-à-dire intent(in)
, intent(out)
ou intent(inout)
comme décrit cette question ):
subroutine bar (a, b)
real, intent(in) :: a
real, intent(inout) :: b
b = b + a
...
Cependant, ne pas spécifier une intention est valide Fortran:
subroutine bar (a, b)
real, intent(in) :: a
real :: b
b = b + a
...
Existe-t-il des différences réelles au-delà de la vérification du temps de compilation pour un argument spécifié comme intent(inout)
et un argument sans intention spécifiée? Y a-t-il quelque chose dont je devrais m'inquiéter si je transforme des intentions en un code plus ancien et sans intention?
Selon The Fortran 2003 Handbook par Adams, et al., Il y a une différence entre un argument d'intention (inout) et un argument sans intention spécifiée. L'argument réel (c'est-à-dire dans l'appelant) dans le cas d'intention (inout) doit toujours être définissable. Si l'intention n'est pas spécifiée, l'argument doit être définissable si l'exécution du sous-programme tente de définir l'argument factice. définissable signifie définir la valeur: dummy_arg = 2.0. De toute évidence, l'argument réel devrait être une variable si cela est fait. Pour l'intention (inout), l'argument réel doit pouvoir être défini, que le sous-programme le fasse ou non. Sans intention spécifiée, cela dépend de ce qui se passe lors de cette invocation particulière du sous-programme - si le sous-programme ne définit pas la variable, c'est OK; si c'est le cas, alors il y a un problème - des cas tels que l'écriture dans un argument réel qui est une constante causera évidemment des problèmes.
Cela ne signifie pas que le compilateur diagnostiquera tous ces cas - ce que la norme exige d'un compilateur pour diagnostiquer est un problème différent. Il serait presque impossible de détecter toutes les erreurs de l'exigence de cas d'intention non spécifiée au moment de la compilation, car les violations dépendent du flux d'exécution du code. Il est beaucoup plus facile pour le compilateur de diagnostiquer le cas intentionnel (inout) et de vous avertir des problèmes avec le code.
Votre question m'incite à me demander (beaucoup à faire en ce moment) si vous pourriez rencontrer une différence de comportement si votre code passe un PARAMÈTRE comme argument réel que votre sous-programme tente ensuite d'écrire. Sans une déclaration INTENT, le compilateur peut laisser faire cela, conduisant à un comportement étrange. Avec la déclaration, je m'attendrais à une erreur de compilation.
Vous et moi pourrions penser qu'il n'y a pas de différence entre INOUT et aucune déclaration INTENT, mais n'oubliez pas qu'il existe de nombreux anciens programmes Fortran et que la compatibilité avec les anciennes versions linguistiques est une caractéristique importante des nouvelles normes. S'il était correct (mais douteux) FORTRAN77, alors beaucoup de gens s'attendent à ce que leur code reste correct (toujours douteux) avec un compilateur Fortran 90+.
Une lecture rapide de la norme de 2003 indique qu'il existe une différence entre INOUT et aucune intention, mais une lecture plus approfondie est nécessaire. Si vous testez cela, faites-nous part de vos conclusions; si j'ai le temps plus tard, je le testerai moi-même et je vous le ferai savoir.
Pour comprendre le rôle de l'intention in/out, vous devez savoir qu'en interne, Fortran effectivement transmet les variables par référence. Ce n'est pas toujours la même chose que de passer par référence.
Si vous passez une sous-section interne d'un tableau 2D à un sous-programme, c'est-à-dire: data(i1:i2, j1:j2)
, alors Fortran copie ces données dans une section contiguë de la mémoire et transmet la nouvelle adresse à la routine. À leur retour, les données sont copiées à leur emplacement d'origine.
En spécifiant INTENT
, le compilateur peut savoir ignorer l'une des opérations de copie.
Il agit non seulement comme une sécurité intégrée pour modifier les données que vous souhaitez conserver inchangées, mais peut également accélérer votre code lorsque vous traitez avec de grands ensembles de données.