En el Item2 en la página 16, (Prefiere concursos, enumeraciones e inlines a #defines), Scott dice:
Además, aunque los buenos compiladores no reservarán almacenamiento para objetos constantes de tipos enteros ...
No entiendo esto Si defino un objeto const, por ejemplo
const int myval = 5;
entonces seguramente el compilador debe reservar algo de memoria (de tamaño int) para almacenar el valor 5?
¿O se almacenan los datos constantes de alguna manera especial?
Esto es más una cuestión de almacenamiento informático, supongo. Básicamente, ¿cómo almacena la computadora los objetos constantes para que no se guarde ningún almacenamiento?
c++
computer-science
usuario619818
fuente
fuente

storage of const objectla fuente de su pregunta tiene poco valor.Respuestas:
Una afirmación un poco más correcta sería que los compiladores no dejarían de lado la memoria de datos para objetos constantes de tipo entero: lo cambiarían por memoria de programa . No hay diferencia entre los dos bajo la arquitectura de Von Neumann, pero en otras arquitecturas, como Harvard, la distinción es bastante importante.
Para comprender completamente lo que está sucediendo, debe recordar cómo el lenguaje ensamblador carga los datos para su procesamiento. Hay dos formas fundamentales de cargar los datos: leer una memoria desde una ubicación específica (denominado modo de direccionamiento directo ) o establecer una constante especificada como parte de la instrucción en sí (denominado modo de direccionamiento inmediato ). Cuando el compilador ve una
const int x = 5declaración seguida deint a = x+x, tiene dos opciones:xse hace referencia al, genere una instrucción de carga inmediata del valor 5En el primer caso, verá una lectura
xen el registro del acumulador , una adición del valor en la ubicación dexa acumulador y una tienda en la ubicación dea. En el segundo caso, verá una carga inmediata de cinco, una suma inmediata de cinco, seguida de una tienda en la ubicación dea. Algunos compiladores pueden darse cuenta de que está agregando una constante a sí mismo, a optimizara = x+xena = 10, y generar una sola instrucción que almacena las diez de la ubicación dea.fuente
No necesariamente. También puede decidir usar el valor bruto 5 en lugar del
myvalcódigo compilado.La diferencia entre
#define MYVAL 5yconst int myval = 5es que, en el primer caso, el compilador no tiene elección, ya que el preprocesador ya reemplazó todas las mencionesMYVALen el código fuente5cuando el compilador llega a ver el código fuente. Sin embargo, en el último caso, hay una opción. Para una compilación de depuración no optimizada, el compilador puede asignar explícitamente aconst int, por lo que en el depurador podrá ver la constantemyval, en lugar de solo el valor bruto 5.fuente
Lo que dice la cita no es del todo correcto.
Un buen compilador no reservará almacenamiento para variables de const estáticas . Si la variable const no es estática y está en el alcance del archivo, debe reservar almacenamiento porque la variable podría ser referenciada desde otra unidad de compilación. Con las optimizaciones de tiempo de enlace, el enlazador podría eliminar el almacenamiento y reescribir las instrucciones que hacen referencia a la variable si puede probar que el programa no genera un puntero a esa variable.
Una razón mucho mejor para usar en
const intlugar de#definees que los depuradores no "ven" las macros, por lo que no puede inspeccionar un#definedvalor d en el depurador.fuente
Robaré la primera oración de la respuesta de Péter Török pero elaboraré de manera diferente: no necesariamente. También puede decidir usar el valor bruto 5 en lugar del
myvalcódigo compilado.Tratar
myvalcomo una variable regular al asignarle espacio en la memoria puede tener implicaciones de rendimiento que varían de minúsculas a severas dependiendo de la arquitectura y cómo maneja la memoria.Trabajando de esa manera, un compilador emitiría una instrucción que diga algo como "registro de carga R con lo que esté en la ubicación de memoria
myval". La ubicación demyvalcomo un operando de la instrucción, por lo que proviene directamente del mismo bloque de datos que la instrucción misma. En las CPU modernas, este valor estará fácilmente disponible en el chip debido a la captación previa de instrucciones. Con la dirección en la mano, la CPU todavía tiene que sacar el valor de la memoria. Eso podría ir rápidamente si la ubicación está cerca en caché o no tan rápido si no lo está. La CPU no solo tiene que salirse del chip para obtener el valor, sino que podría obligarla a eliminar otros datos más útiles de la memoria caché que tendrán que ser devueltos más tarde. Cuando el programa se ejecuta en un sistema operativo que virtualiza la memoria, el acceso a esa ubicación puede causar un error de página, lo que puede provocar que el programa se suspenda hasta que la página requerida se introduzca en la RAM a través de E / S periféricas (p. Ej., Disco),Al cablear el valor constante en el código objeto, el compilador emitiría una instrucción como "cargar el registro R con el valor
5". Al igual que la dirección de memoria descrita anteriormente,5sería un operando para la instrucción y estaría disponible de la misma manera (es decir, captado previamente). Ahí es donde termina la similitud, porque la CPU ahora tiene todo lo que necesita para ponerla5en el registro R y continuar con su negocio. Dado que las direcciones y los registros suelen ser del mismo tamaño, no hay diferencia en el número de bytes que ocupa la instrucción y la ejecución real se lleva a cabo con cero posibilidades de fallas en la caché y fallas de página que pueden ocurrir cuando pescas algo sin memoria.El compilador podría, como señaló Péter, asignar espacio y un símbolo para las
myvalcompilaciones de depuración. No habría ningún daño al hacer esto y aún cablear su valor, ya que el valor sigue siendo el mismo, pase lo que pase y el símbolo realmente está ahí para que los humanos lo usemos en la depuración.Tenga en cuenta que esto solo se aplica a los valores que se pueden mantener en los registros, porque los registros son enteros por naturaleza. Otras constantes terminarán en la memoria.
fuente
El compilador sustituirá el número cinco siempre que se use la variable 'myval'.
fuente
El compilador puede considerar los valores constantes como operandos inmediatos. Los operandos inmediatos no requieren almacenamiento de datos. El compilador puede tratar:
lo mismo que
El valor 5 no se almacena en la memoria de datos, sino como parte de la secuencia de instrucciones.
El compilador debe reservar el almacenamiento de datos en los casos en que se pueda tomar la dirección del valor. Incluso en ese caso, el compilador seguirá utilizando operaciones inmediatas cuando se use el valor de myVal.
fuente