"Hai mai cambiato il valore di 4?" - come è arrivato questo quiz Hayes-Thomas?

24

Nel 1989 Felix Lee, John Hayes e Angela Thomas hanno scritto un test di hacker prendendo la forma di un quiz con molte battute interne, come " Hai mangiato muffe viscide? "

Sto considerando le seguenti serie:

0015 Ever change the value of 4?
0016 ... Unintentionally?
0017 ... In a language other than Fortran?

C'è un particolare aneddoto che rende il numero "4" particolare nella serie?

Alcune implementazioni di Fortran hanno permesso di modificare il valore delle costanti? Era possibile in altre lingue di uso comune in quel momento?

    
posta Michael Le Barbier Grünewald 29.08.2014 - 12:42
fonte

3 risposte

32

Nei vecchi tempi (anni '70 e prima) alcuni computer non avevano alcuna MMU (e questo è vero oggi per microcontrollori molto economici).

Su tali sistemi, non c'è protezione della memoria, quindi nessun segmento di sola lettura nello spazio indirizzo , e un buggy il programma potrebbe sovrascrivere una costante (nella memoria dei dati, o anche all'interno del codice macchina).

I compilatori Fortran in quel momento hanno superato gli argomenti per riferimento . Quindi se hai fatto CALL FUN(4) e SUBROUTINE FUN(I) ha il suo corpo che cambia I - ad es. con una dichiarazione I = I + 1 nel suo corpo, potresti avere un disastro, cambiando 4 in 5 nel chiamante (o peggio).

Questo era vero anche per i primi microcomputer come l'originale PC IBM AT del 1984, con MS-DOS

FWIW, sono abbastanza vecchio da aver usato, come adolescente nei primi anni '70, questi computer: IBM1620 e CAB500 (in un museo: questi sono computer dell'era degli anni '60!). IBM1620 era piuttosto divertente: veniva utilizzato nelle tabelle di memoria per aggiunte e moltiplicazioni (e se si sovrascrivevano queste tabelle, ne seguiva il caos). Quindi non solo potresti sovrascrivere un 4, ma potresti perfino sovrascrivere ogni futura aggiunta 2 + 2 o moltiplicazioni 7 * 8 (ma ho davvero dimenticato questi dettagli sporchi, quindi potrebbe essere sbagliato).

Oggi potresti sovrascrivere il codice BIOS nella memoria flash, se sei abbastanza perseverante. Purtroppo, non mi sento più così divertente, quindi non ho mai provato. (Ho anche paura di installare alcuni LinuxBios sulla mia scheda madre).

Sugli attuali computer e sistemi operativi che passano una costante per riferimento e la cambiano all'interno del callee provocherà solo una violazione della segmentazione , che suona familiare a molti sviluppatori C o C ++.

BTW: essere pignoli: sovrascrivere 4 non è una questione di linguaggio, ma di implementazione.

    
risposta data 29.08.2014 - 13:03
fonte
7

È 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.

    
risposta data 31.08.2014 - 08:36
fonte
5

In FORTRAN, quando una costante viene passata a un'altra procedura, non è più protetta. Questo è quello a cui si riferiscono. Altri linguaggi di programmazione popolari nello stesso periodo erano C e Pascal che non avevano (e ancora non hanno) questo problema. Forse ci sono linguaggi di programmazione più vecchi di cui non sono a conoscenza che hanno lo stesso problema.

    
risposta data 29.08.2014 - 13:16
fonte

Leggi altre domande sui tag