Był to niezamierzony efekt uboczny strategii oceny wywołań funkcji FORTRAN w połączeniu z błędną optymalizacją kompilatora.
FORTRAN II wprowadził zdefiniowane przez użytkownika funkcje i podprogramy, których argumenty przekazywane są przez odwołanie . (No nie wiem. Prawdopodobnie było to wtedy bardziej wydajne niż przekazywanie wartości na sprzęcie IBM.)
Zwykle przekazywanie przez odniesienie oznacza, że musisz przekazać wartość l (jak zmienna) zamiast wartości r. Ale projektanci FORTRAN postanowili być pomocni i pozwolić ci przekazać wartości r jako argumenty. Kompilator automatycznie wygeneruje dla ciebie zmienną. Więc jeśli napisałeś:
CALL SUBFOO(X + Y, 4)
kompilator przekształciłby to za kulisami w coś podobnego
TEMP1 = X + Y
TEMP2 = 4
CALL SUBFOO(TEMP1, TEMP2)
Istniała również wspólna optymalizacja kompilatora zwana „pulą literałów”, która konsolidowałaby wiele wystąpień tej samej stałej liczbowej w tej samej automatycznie generowanej zmiennej. (Kilka języków w rodzinie C wymaga tego do literałów łańcuchowych.) Więc jeśli napisałeś
CALL SUBBAR(4)
CALL SUBBAZ(4)
byłoby to traktowane tak, jakby tak było
FOUR = 4
CALL SUBBAR(FOUR)
CALL SUBBAZ(FOUR)
co wydaje się całkowicie rozsądną rzeczą, dopóki nie pojawi się podprogram, który zmienia wartość jego parametrów.
SUBROUTINE SUBBAR(X)
!...lots of code...
X = 5
!...lots of code...
END SUBROUTINE SUBBAR
Bum! CALL SUBBAR(4)
zmieniłem wartość 4 w literalnej puli na 5. A potem zastanawiasz się, dlaczego SUBBAZ
zakładasz, że przekazałeś jej 5 zamiast 4
faktycznie napisanej w kodzie.
Nowsze wersje Fortran łagodzą ten problem, pozwalając zadeklarować INTENT
zmienną jako IN
lub OUT
i dając ci błąd (lub przynajmniej ostrzeżenie), jeśli przekażesz stałą jako OUT
parametr.