È stato un effetto collaterale involontario della strategia di valutazione delle chiamate di funzione FORTRAN in combinazione con un'errata ottimizzazione del compilatore.
FORTRAN II ha introdotto funzioni e subroutine definite dall'utente con i relativi argomenti passati per riferimento . (Perché, non lo so, probabilmente era più efficiente del pass-by-value sull'hardware IBM dell'epoca.)
Normalmente, pass-by-reference significa che devi passare un valore l (come una variabile) invece di un valore r. Ma i progettisti di FORTRAN hanno deciso di essere d'aiuto e consentono di passare comunque i valori R come argomenti. Il compilatore genererebbe automaticamente una variabile per te. Quindi, se hai scritto:
CALL SUBFOO(X + Y, 4)
il compilatore convertirà questo dietro le quinte in qualcosa di simile
TEMP1 = X + Y
TEMP2 = 4
CALL SUBFOO(TEMP1, TEMP2)
C'era anche una comune ottimizzazione del compilatore chiamata "pool letterale", che avrebbe consolidato più istanze della stessa costante numerica nella stessa variabile generata automaticamente. (Diverse lingue nella famiglia C richiedono questo per i letterali stringa.) Quindi, se hai scritto
CALL SUBBAR(4)
CALL SUBBAZ(4)
questo sarebbe trattato come se fosse
FOUR = 4
CALL SUBBAR(FOUR)
CALL SUBBAZ(FOUR)
che sembra una cosa perfettamente ragionevole da fare fino a hai un sottoprogramma che cambia il valore dei suoi parametri.
SUBROUTINE SUBBAR(X)
!...lots of code...
X = 5
!...lots of code...
END SUBROUTINE SUBBAR
Boom! CALL SUBBAR(4)
ha cambiato il valore del 4 nel pool letterale in un 5. E poi ti chiedi perché SUBBAZ
stia assumendo che tu abbia passato un 5 invece del 4
che hai effettivamente scritto nel codice.
Le versioni più recenti di Fortran mitigano questo problema permettendoti di dichiarare il INTENT
di una variabile come IN
o OUT
e dandoti un errore (o almeno un avvertimento) se passi una costante come% parametroOUT
.