12
votes

Fortran conserve-t-il la valeur des variables internes via des appels de fonction et de sous-programme?

Après de nombreux débogage douloureux, je crois que j'ai trouvé une propriété unique de Fortran que j'aimerais vérifier ici à Stackoverflow.

Ce que j'ai remarqué, c'est que, à tout le moins, la valeur de Les variables logiques internes sont préservées dans une fonction ou des appels de sous-programme.

Voici un exemple de code pour illustrer mon point: xxx

Ceci est la sortie: xxx

Comme vous pouvez le constater, il apparaît qu'une fois la fonction ou le sous-programme appelé une fois, la variable logique négative , si elle est commutée sur .True. . reste en tant que tel malgré l'initialisation de négatif à .false. dans la déclaration de déclaration type.

Je pourrais, bien sûr , corrigez ce problème en ajoutant juste une ligne négatif = .false. Après avoir déclaré la variable dans ma fonction et ma sous-programme.

Cependant, il me semble très étrange que cela soit nécessaire que cela soit nécessaire.

pour le bien de la portabilité et la réutilisabilité de code, 'T La langue (ou le compilateur peut-être) nécessite une réinitialisation de toutes les variables internes chaque fois que le sous-programme ou la fonction est appelé?


0 commentaires

3 Réponses :


4
votes

Ce n'est pas trop différent de statique Fonction-scopé des variables en C ou C ++.

La conception de la langue de programmation était à ses balbutiements, retour lorsque FORTRAN était développé. S'il était conçu à partir de zéro aujourd'hui, bon nombre de la conception Les décisions auraient été différentes.

à l'origine, fortran n'a même pas soutenu la récursion, il n'y avait pas de mémoire dynamique Allocation, les programmes ont joué toutes sortes de jeux de type punning avec communs blocs et équivalence déclarations, procédures pourraient avoir plusieurs points d'entrée .... donc le Le modèle de mémoire était fondamentalement pour le compilateur / lieur pour tout mettre en place, même local variables et constantes littérales numériques, dans des emplacements de stockage fixes, plutôt que sur la pile. Si vous le souhaitez, vous pouvez même écrire du code qui a changé la valeur de «2» à "42"!

À l'heure actuelle, il y a un énormément de la héritage Fortran Le code et les écrivains compilateurs vont aux grandes longueurs pour préserver la sémantique compatible avec l'arrière. Je ne peux pas citer le chapitre et le verset de la norme qui exige le comportement que vous avez constaté, ni sa justification, mais il semble raisonnable que la compatibilité ascendante soit une compatibilité rédactable a compromis les sensibilités de conception de la langue moderne, dans ce cas.


3 commentaires

Il y a sans aucun doute quelques problèmes hérités de Fortran qui, étant-il écrit aujourd'hui de la lecture, seraient traités différemment, mais s'il vous plaît - ne faites pas cela comme si c'est une langue héritée. Bien au contraire - dans de nombreux termes, il dispose que d'autres langues "modernes" d'acquérir (par exemple, sur C.L.F. Les discussions sont souvent liées à la norme F03 / la plus récente C, ce qui est ce que C99?)


@IDIGAS: bons points! Je ne voulais pas impliquer que Fortran est un fossile ... C'est juste que l'aspect héritage semblait le plus sur la question de CMDRGuard, c'est ce que je me concentrais.


Évidemment, j'ai mal compris; Désolé pour ça. Mon erreur. Le reste de votre réponse est assez bien mis.



17
votes

Pour répondre à votre question: Oui FORTRAN conserve la valeur des variables internes via des appels de fonction et de sous-programme .

sous certaines conditions ...

Si vous déclarez une variable interne avec l'attribut Enregistrer, la valeur est enregistrée d'un appel à la suivante. Ceci est bien sûr utile dans certains cas.

Toutefois, votre question est une réaction courante lors de l'apprentissage d'abord sur l'une des gothas de Fortran: Si vous initiez une variable interne dans sa déclaration, elle acquiert automatiquement l'attribut de sauvegarde. Vous avez fait exactement cela dans vos sous-programmes. Ceci est conforme standard. Si vous ne voulez pas que cela se produise, n'initialisez pas dans la déclaration.

C'est la cause de beaucoup de surprise et de plainte de (certains) nouveaux arrivants à la langue. Mais peu importe à quel point ils se plaignent de ne pas changer pour que vous ne puissiez pas avoir à (a) savoir à ce sujet et (b) le programme de conscience de celui-ci.


4 commentaires

Je crois (pour être sûr que je devrais aller vérifier la norme que je n'ai pas avec moi en ce moment) qu'à partir de F2003, toutes les variables ont l'attribut de sauvegarde.


@rook: Dans quelles circonstances les variables ont-elles automatiquement Enregistrer ?


@jvriesem - Je ne comprends pas la question. "Dans quelles circonstances"? Pourriez-vous élaborer?


@Rook: Bien sûr. Je sais que si un sous-programme est déclaré élémental , il est automatiquement déclaré pur . De même, je sais que les variables de module (au moins certains) ont automatiquement l'attribut Enregistrer sans l'indiquer, mais je ne sais pas s'il y a d'autres contextes que le enregistre L'attribut est implicite et / ou ajouté automatiquement. Je me demande si vous connaissez des situations dans lesquelles une variable est acceptée implicitement (comme si elle avait l'attribut Enregistrer ), sans le programmateur la spécifie réellement.



4
votes

Ceci a été discuté à plusieurs reprises ici, plus récemment à Assignement Fortran sur déclaration et enregistrement Attribut Gotcha

Vous n'avez pas à découvrir ce comportement par expérimentation, il est clairement indiqué dans les meilleurs manuels.

Différentes langues sont différentes et ont des comportements différents.

Il y a une raison historique de ce comportement. De nombreux compilateurs pour Fortran 77 et plus tôt ont préservé les valeurs de toutes les variables locales sur des appels de procédures. Les programmeurs n'étaient pas censés dépendre de ce comportement mais beaucoup l'ont fait. Selon la norme, si vous vouliez une variable locale (non fréquente) de conserver sa valeur, vous devez utiliser "Enregistrer". Mais de nombreux programmeurs ont ignoré cela. Dans ces programmes d'époque ont été moins fréquemment portés à différentes plateformes et compilateurs, des hypothèses incorrectes pourraient ne jamais être remarquées. Il est courant de trouver ce problème dans les programmes hérités - les compilateurs de Fortran actuels fournissent généralement un commutateur de compilateur pour que toutes les variables soient enregistrées. Il serait idiot que la norme linguistique exige que toutes les variables locales conservent leurs valeurs. Mais une exigence intermédiaire qui permettrait de sauver de nombreux programmes négligents avec "Save" serait d'exiger que toutes les variables initialisées dans leurs déclarations ont automatiquement l'attribut de sauvegarde. Par conséquent, ce que vous avez découvert ....


0 commentaires