Це був ненавмисний побічний ефект стратегії оцінювання викликів функції FORTRAN у поєднанні з помилковою оптимізацією компілятора.
FORTRAN II представив визначені користувачем функції та підпрограми зі своїми аргументами, переданими посиланням . (Чому я не знаю. Це, мабуть, було більш ефективно, ніж прохідна вартість на апаратному забезпеченні IBM того часу.)
Зазвичай передача посилань означає, що вам доведеться передавати l-значення (як змінну) замість r-значення. Але дизайнери FORTRAN вирішили бути корисними і дозволяють вам передавати r-значення як аргументи в будь-якому випадку. Компілятор автоматично генерує змінну для вас. Отже, якщо ви написали:
CALL SUBFOO(X + Y, 4)
компілятор перетворив би це за кадром у щось подібне
TEMP1 = X + Y
TEMP2 = 4
CALL SUBFOO(TEMP1, TEMP2)
Існувала також загальна оптимізація компілятора, що називається "буквальний пул", яка об'єднала б декілька екземплярів однієї чисельної константи в одну і ту ж автоматично сгенеровану змінну. (Декілька мов сімейства C вимагають цього для рядкових літералів.) Отже, якщо ви писали
CALL SUBBAR(4)
CALL SUBBAZ(4)
це трактується так, як ніби
FOUR = 4
CALL SUBBAR(FOUR)
CALL SUBBAZ(FOUR)
що видається цілком розумною справою, поки у вас не з’явиться підпрограма, яка змінює значення її параметрів.
SUBROUTINE SUBBAR(X)
!...lots of code...
X = 5
!...lots of code...
END SUBROUTINE SUBBAR
Бум! CALL SUBBAR(4)
змінив значення 4 у прямому пулі на 5. І тоді вам залишається цікаво, чому SUBBAZ
припускаєте, що ви передали його 5 замість того, що 4
ви насправді написали в коді.
Більш новіші версії Fortran пом'якшують цю проблему, дозволяючи вам оголосити INTENT
змінну як IN
або OUT
і подати вам помилку (або принаймні попередження), якщо ви передаєте константу як OUT
параметр.