En 1989, Felix Lee, John Hayes y Angela Thomas escribieron una prueba de Hacker que tomaba la forma de un cuestionario con muchas bromas internas, como “ ¿Comes moldes de limo? "
Estoy considerando la siguiente serie:
0015 Ever change the value of 4?
0016 ... Unintentionally?
0017 ... In a language other than Fortran?
¿Hay alguna anécdota en particular que haga que el número "4" sea particular en la serie?
¿Alguna implementación de Fortran permitió modificar el valor de las constantes? ¿Era esto posible en otros idiomas de uso común en ese momento?
4
a5
las listas de números enteros internados.4 = 5
Fue posible.Respuestas:
En los viejos tiempos (1970 y antes) algunas computadoras no tenían ninguna MMU (y esto es cierto hoy en día para microcontroladores muy baratos).
En tales sistemas, no hay protección de memoria, por lo que no hay un segmento de solo lectura en el espacio de direcciones , y un programa con errores podría sobrescribir una constante (ya sea en la memoria de datos o incluso dentro del código de la máquina).
Los compiladores de Fortran en ese momento pasaron argumentos formales por referencia . Entonces, si lo hizo
CALL FUN(4)
ySUBROUTINE FUN(I)
su cuerpo está cambiandoI
, por ejemplo, con una declaraciónI = I + 1
en su cuerpo, podría tener un desastre, cambiando 4 a 5 en la persona que llama (o peor).Esto también fue cierto en los primeros microordenadores como el IBM PC AT original de 1984, con MS-DOS
FWIW, soy lo suficientemente mayor como para haber usado, cuando era adolescente a principios de la década de 1970, tales computadoras: IBM1620 y CAB500 (en un museo: ¡estas son computadoras de la era de la década de 1960!). El IBM1620 fue bastante divertido: se usaba en tablas de memoria para adiciones y multiplicaciones (y si sobrescribió estas tablas, se produjo el caos). Entonces, no solo podría sobrescribir un 4, sino que incluso podría sobrescribir cada futura adición de 2 + 2 o multiplicaciones de 7 * 8 (pero realmente olvidé estos detalles sucios, por lo que podría estar equivocado).
Hoy, puede sobrescribir el código del BIOS en la memoria flash, si es lo suficientemente perseverante. Lamentablemente, ya no me siento tan divertido, así que nunca lo intenté. (Incluso tengo miedo de instalar algunos LinuxBios en mi placa base).
En las computadoras y sistemas operativos actuales, pasar una constante por referencia y cambiarla dentro de la persona que llama solo provocará una violación de la segmentación , que suena familiar para muchos desarrolladores de C o C ++.
Por cierto: ser quisquilloso: sobrescribir 4 no es una cuestión de lenguaje, sino de implementación.
fuente
gfortran
. Las constantes se colocan en su segmento y se pasan por referencia a una subrutina. Por defecto, la sección constante es de solo lectura, por lo que el error de protección de memoria mata el programa.Fue un efecto secundario involuntario de la estrategia de evaluación de llamadas de función de FORTRAN en combinación con una optimización de compilador errónea.
FORTRAN II introdujo funciones y subrutinas definidas por el usuario con sus argumentos pasados por referencia . (Por qué, no lo sé. Probablemente fue más eficiente que el paso por valor en el hardware de IBM de la época).
Normalmente, pasar por referencia significa que tiene que pasar un valor l (como una variable) en lugar de un valor r. Pero los diseñadores de FORTRAN decidieron ser útiles y permitirle pasar valores r como argumentos de todos modos. El compilador generaría automáticamente una variable para usted. Entonces, si escribiste:
el compilador convertiría esto detrás de escena en algo como
También había una optimización común del compilador llamada "grupo literal", que consolidaría múltiples instancias de la misma constante numérica en la misma variable autogenerada. (Varios lenguajes de la familia C requieren esto para los literales de cadena). Entonces, si escribió
esto se trataría como si fuera
lo cual parece una cosa perfectamente razonable que hacer hasta que tenga un subprograma que cambie el valor de sus parámetros.
¡Auge!
CALL SUBBAR(4)
cambió el valor del 4 en el grupo literal a un 5. Y luego se pregunta por quéSUBBAZ
está asumiendo que pasó un 5 en lugar del4
que realmente escribió en el código.Las versiones más nuevas de Fortran mitigan este problema al permitirle declarar la
INTENT
variable comoIN
oOUT
, y al darle un error (o al menos una advertencia) si pasa una constante comoOUT
parámetro.fuente
En FORTRAN, cuando se pasa una constante a otro procedimiento, ya no está protegida. A eso se refieren. Otros lenguajes de programación populares en ese mismo tiempo fueron C y Pascal que no tenían (y aún no tienen) este problema. Tal vez hay lenguajes de programación más antiguos que no conozco que tengan el mismo problema.
fuente
.rodata
segmento de solo lectura (como lo hacen los compiladores actuales), cambiarlo no alterará la constante, pero provocaría un SEGV.