una - ¿Dónde se almacenan las variables constantes en C?
variables y constantes en c++ (12)
Me pregunto dónde se almacenan las variables constantes. ¿Está en la misma área de memoria que las variables globales? ¿O está en la pila?
Algunas constantes ni siquiera se almacenan.
Considere el siguiente código: int x = foo(); x *= 2;
int x = foo(); x *= 2;
. Lo más probable es que el compilador convierta la multiplicación en x = x+x;
ya que eso reduce la necesidad de cargar el número 2 de la memoria.
Cómo se almacenan es un detalle de implementación (depende del compilador).
Por ejemplo, en el compilador de GCC, en la mayoría de las máquinas, las variables de solo lectura, las constantes y las tablas de salto se colocan en la sección de texto.
Considera el código:
const int i = 0;
static const int k = 99;
int function(void)
{
const int j = 37;
totherfunc(&j);
totherfunc(&i);
//totherfunc(&k);
return(j+3);
}
Generalmente, puedo almacenarme en el segmento de texto (es una variable de solo lectura con un valor fijo). Si no está en el segmento de texto, se almacenará junto a las variables globales. Dado que se inicializa a cero, podría estar en la sección ''bss'' (donde generalmente se asignan variables cerradas) o en la sección ''datos'' (donde las variables inicializadas suelen asignarse).
Si el compilador está convencido de que k
no está en uso (lo cual podría ser dado que es local en un solo archivo), es posible que no aparezca en el código del objeto. Si la llamada a totherfunc()
que hace referencia a k
no fue comentada, entonces k
debería tener asignada una dirección en alguna parte, probablemente estaría en el mismo segmento que i
.
La constante (si es una constante, ¿sigue siendo una variable?) j
probablemente aparezca en la pila de una implementación C convencional. (Si estuviera preguntando en el grupo de noticias comp.std.c, alguien mencionaría que el estándar no dice que las variables automáticas aparecen en la pila; afortunadamente, ¡SO no es comp.std.c!)
Tenga en cuenta que obligué a las variables a aparecer porque las pasé por referencia, presumiblemente a una función que espera un puntero a un entero constante. Si las direcciones nunca se tomaron, entonces j
y k
podrían optimizarse completamente fuera del código. Para eliminar i
, el compilador debería conocer todo el código fuente de todo el programa; puede acceder a él en otras unidades de traducción (archivos fuente) y, por lo tanto, no puede eliminarse fácilmente. Doblemente, no, si el programa se entrega a la carga dinámica de bibliotecas compartidas, una de esas bibliotecas puede depender de esa variable global.
(Estilísticamente, las variables i
y j
deberían tener nombres más largos y significativos, ¡esto es solo un ejemplo!)
Debe almacenarse en el segmento de texto ya que son variables de solo lectura. http://shirleyanengineer.blogspot.in/2017/05/memory-layout-of-process.html
Depende de tu compilador, las capacidades de tu sistema y tu configuración durante la compilación.
gcc
puts constantes de solo lectura en la sección .text
, a menos que se indique lo contrario.
Esto es en su mayoría una suposición educada, pero yo diría que las constantes generalmente se almacenan en las instrucciones reales de la CPU de su programa compilado, como datos inmediatos. En otras palabras, la mayoría de las instrucciones incluyen espacio para que la dirección obtenga datos, pero si es una constante, el espacio puede contener el valor mismo.
Global y constante son dos palabras clave completamente separadas. Puedes tener uno o el otro, ninguno o ambos.
Donde su variable, entonces, se almacena en la memoria depende de la configuración. Lea un poco sobre el heap y la stack , que le dará algunos conocimientos para hacer más preguntas (y si se puede, mejor y más específico).
Por lo general, se almacenan en la sección de datos de solo lectura (mientras que la sección de variables globales tiene permisos de escritura). Por lo tanto, intentar modificar la constante tomando su dirección puede dar como resultado una violación de acceso también conocida como segfault.
Pero realmente depende de su hardware, sistema operativo y compilador.
Puede que no se almacene en absoluto.
Considera un código como este:
#import<math.h>//import PI
double toRadian(int degree){
return degree*PI*2/360.0;
}
Esto permite al programador reunir la idea de lo que está sucediendo, pero el compilador puede optimizar parte de eso, y la mayoría de los compiladores lo hacen, evaluando expresiones constantes en tiempo de compilación, lo que significa que el valor PI puede no estar en el programa resultante. en absoluto.
Según la segmentación de datos que sigue un procesador en particular, tenemos cinco segmentos:
- Segmento de código: almacena solo código, ROM
- Segmento BSS (o Bloque iniciado por símbolos) - Almacena variables globales y estáticas inicializadas
- Segmento de pila: almacena todas las variables locales y otras informaciones sobre la dirección de devolución de funciones, etc.
- Segmento de montón: todas las asignaciones dinámicas ocurren aquí
- Segmento de datos: almacena variables globales y estáticas no inicializadas
Tenga en cuenta que la diferencia entre el BSS y el segmento de datos es que la tienda anterior inicializó variables globales y estáticas y las posteriores almacena las no iniciadas.
Ahora, ¿por qué estoy hablando de la segmentación de datos cuando debo decir dónde están almacenadas las variables constantes ... hay una razón para ello ...
Cada segmento tiene una región protegida contra escritura donde se almacenan todas las constantes.
Por ejemplo,
si tengo una const int que es una variable local, entonces se almacena en la región protegida de escritura del segmento de la pila. y si tengo un global que se inicializa const var, entonces se almacena en BSS y si tengo un const var no inicializado, entonces se almacena en el segmento de datos ...
Para resumir, "const" es solo un QUALIFIER de datos, lo que significa que primero el compilador debe decidir qué segmento debe almacenarse la variable y luego si la variable es const, entonces califica para ser almacenada en la región protegida contra escritura de ese segmento en particular.
Espero que esto aclare la mayoría de los malentendidos ... :-)
Cualquier comentario adicional es bienvenido ... :-)
Solo como un complemento, ya que sabe que durante el proceso de vinculación se decide la distribución de la memoria del último ejecutable. Hay una sección más llamada COMÚN en la que se colocan los símbolos comunes de los diferentes archivos de entrada. Esta sección común en realidad cae bajo la sección .bss.
por supuesto, no, porque
1) segmento bss almacenado variables no inilizadas, obviamente, otro tipo está allí.
(I) large static and global and non constants and non initilaized variables it stored .BSS section.
(II) second thing small static and global variables and non constants and non initilaized variables stored in .SBSS section this included in .BSS segment.
2) segmento de datos es variables iniciadas tiene 3 tipos,
(I) large static and global and initlaized and non constants variables its stord in .DATA section.
(II) small static and global and non constant and initilaized variables its stord in .SDATA1 sectiion.
(III) small static and global and constant and initilaized OR non initilaized variables its stord in .SDATA2 sectiion.
menciono arriba, los medios pequeños y grandes dependen del compilador, por ejemplo, medios pequeños <de 8 bytes y medios grandes> de 8 bytes e iguales valores.
pero mi duda es la constante local, ¿dónde se desarrollará ??????