Itu adalah efek samping yang tidak disengaja dari strategi evaluasi panggilan fungsi FORTRAN dalam kombinasi dengan optimasi kompiler yang salah.
FORTRAN II memperkenalkan fungsi dan subrutin yang ditentukan pengguna dengan argumennya yang disahkan oleh referensi . (Ya, saya tidak tahu. Mungkin itu lebih efisien daripada nilai kelulusan pada perangkat keras IBM saat itu.)
Biasanya, pass-by-reference berarti Anda harus melewati nilai-l (seperti variabel) alih-alih nilai-r. Tetapi para perancang FORTRAN memutuskan untuk membantu dan membiarkan Anda memberikan nilai-r sebagai argumen. Kompiler akan secara otomatis menghasilkan variabel untuk Anda. Jadi, jika Anda menulis:
CALL SUBFOO(X + Y, 4)
kompiler akan mengonversi ini di belakang layar menjadi sesuatu seperti
TEMP1 = X + Y
TEMP2 = 4
CALL SUBFOO(TEMP1, TEMP2)
Ada juga optimasi kompiler umum yang disebut "kumpulan literal", yang akan mengkonsolidasikan beberapa contoh dari konstanta numerik yang sama ke dalam variabel yang dihasilkan secara otomatis yang sama. (Beberapa bahasa dalam keluarga C membutuhkan ini untuk string literal.) Jadi, jika Anda menulis
CALL SUBBAR(4)
CALL SUBBAZ(4)
ini akan diperlakukan seolah-olah demikian
FOUR = 4
CALL SUBBAR(FOUR)
CALL SUBBAZ(FOUR)
yang tampaknya seperti hal yang masuk akal untuk dilakukan sampai Anda memiliki subprogram yang mengubah nilai parameternya.
SUBROUTINE SUBBAR(X)
!...lots of code...
X = 5
!...lots of code...
END SUBROUTINE SUBBAR
Ledakan! CALL SUBBAR(4)
mengubah nilai 4 dalam kumpulan literal ke 5. Dan kemudian Anda bertanya-tanya mengapa SUBBAZ
dengan asumsi Anda memberikannya 5 bukannya 4
Anda benar-benar menulis dalam kode.
Versi yang lebih baru dari Fortran mengurangi masalah ini dengan membiarkan Anda mendeklarasikan INTENT
variabel sebagai IN
atau OUT
, dan memberi Anda kesalahan (atau setidaknya peringatan) jika Anda memberikan konstanta sebagai OUT
parameter.