Dies war ein unbeabsichtigter Nebeneffekt der Funktionsaufruf-Bewertungsstrategie von FORTRAN in Kombination mit einer fehlerhaften Compiler-Optimierung.
FORTRAN II führte benutzerdefinierte Funktionen und Unterprogramme mit ihren als Referenz übergebenen Argumenten ein . (Ich weiß nicht, warum. Es war wahrscheinlich effizienter als die Weitergabe von Werten auf IBM-Hardware der Zeit.)
Normalerweise bedeutet Referenzübergabe, dass Sie einen l-Wert (wie eine Variable) anstelle eines r-Werts übergeben müssen. Die Designer von FORTRAN haben sich jedoch dazu entschlossen, hilfreich zu sein und Sie trotzdem r-Werte als Argumente übergeben zu lassen. Der Compiler generiert automatisch eine Variable für Sie. Also, wenn Sie geschrieben haben:
CALL SUBFOO(X + Y, 4)
Der Compiler würde dies hinter den Kulissen in so etwas wie konvertieren
TEMP1 = X + Y
TEMP2 = 4
CALL SUBFOO(TEMP1, TEMP2)
Es gab auch eine allgemeine Compiler-Optimierung, die als "Literal-Pool" bezeichnet wurde und mehrere Instanzen derselben numerischen Konstante in derselben automatisch generierten Variablen zusammenfasste. (Einige Sprachen in der C-Familie erfordern dies für Zeichenkettenliterale.) Also, wenn Sie geschrieben haben
CALL SUBBAR(4)
CALL SUBBAZ(4)
Dies würde so behandelt, als ob es wäre
FOUR = 4
CALL SUBBAR(FOUR)
CALL SUBBAZ(FOUR)
Das scheint eine vernünftige Sache zu sein, bis Sie ein Unterprogramm haben, das den Wert seiner Parameter ändert.
SUBROUTINE SUBBAR(X)
!...lots of code...
X = 5
!...lots of code...
END SUBROUTINE SUBBAR
Boom! CALL SUBBAR(4)
änderte den Wert der 4 im Literal-Pool in eine 5. Und dann wundern Sie sich, warum SUBBAZ
Sie davon ausgehen, dass Sie eine 5 statt der 4
tatsächlich im Code geschriebenen übergeben haben.
Neuere Versionen von Fortran verringern dieses Problem, indem Sie INTENT
eine Variable als IN
oder deklarieren OUT
und einen Fehler (oder zumindest eine Warnung) ausgeben, wenn Sie eine Konstante als OUT
Parameter übergeben.