È stato un effetto collaterale involontario della strategia di valutazione delle chiamate di funzione FORTRAN in combinazione con un'ottimizzazione del compilatore errata.
FORTRAN II ha introdotto funzioni e subroutine definite dall'utente con i loro argomenti passati per riferimento . (Perché, non lo so. Probabilmente era più efficiente del valore pass-by 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 di lasciarti comunque passare valori-r come argomenti. Il compilatore genererebbe automaticamente una variabile per te. Quindi, se hai scritto:
CALL SUBFOO(X + Y, 4)
il compilatore lo convertirà dietro le quinte in qualcosa del genere
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 della 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 quando non si ha un sottoprogramma che modifica 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 di 4 nel pool letterale in 5. E poi ti stai chiedendo perché SUBBAZ
stai assumendo di averlo passato un 5 invece di quello che 4
hai effettivamente scritto nel codice.
Le versioni più recenti di Fortran mitigano questo problema consentendo di dichiarare la INTENT
variabile come IN
o OUT
e dandoti un errore (o almeno un avviso) se passi una costante come OUT
parametro.