psicograficas - tipos de segmentacion de mercado ejemplos
¿Por qué const int main=195 resulta en un programa de trabajo pero sin la const termina en una falla de segmentación? (2)
Considere seguir el programa C (ver demostración en vivo here ).
const int main = 195;
Sé que en el mundo real ningún programador escribe código así, porque no tiene ningún propósito útil y no tiene ningún sentido. Pero cuando const
palabra clave const
desde arriba del programa, resulta inmediatamente en un error de segmentación . ¿Por qué? Estoy ansioso por saber la razón detrás de esto.
GCC 4.8.2 da la siguiente advertencia al compilarlo.
advertencia: ''main'' es usualmente una función [-Wmain]
const int main = 195; ^
¿Por qué la presencia y la ausencia de la palabra clave const
hacen una diferencia aquí en el comportamiento del programa?
En C, main
a nivel global es casi siempre una función.
El uso de main
como variable en el ámbito global hace que el comportamiento del programa sea indefinido.
( Podría ser el caso de que al escribir const
el compilador optimice la variable a una constante y, por lo tanto, el comportamiento de su programa sea diferente. Pero el comportamiento del programa aún no está definido).
Observe cómo el valor 195 corresponde a la instrucción ret
(return from function) en 8086 compatibles. Esta definición de main
se comporta como si la hubieras definido como int main() {}
cuando se ejecuta.
En algunas plataformas, los datos const
se cargan en una región de memoria ejecutable pero no grabable, mientras que los datos mutables (es decir, los datos const
no calificados) se cargan en una región de memoria escribible pero no ejecutable. Por esta razón, el programa "funciona" cuando se declara main
como const
pero no cuando se deja fuera del calificador const
.
Tradicionalmente, los binarios contenían tres segmentos:
- El segmento de
text
(si lo admite la arquitectura) está protegido contra escritura y es ejecutable, y contiene código ejecutable, variables deconst
calificadas de duración de almacenamiento y literales de cadena - El segmento de
data
es grabable y no se puede ejecutar. Contiene variables no calificadasconst
con duración de almacenamiento estática y (en tiempo de ejecución) objetos con duración de almacenamiento asignada - El segmento
bss
es similar al segmento dedata
pero se inicializa a todos los ceros. Contiene variables de duración de almacenamiento estático no calificadasconst
que se han declarado sin un inicializador - El segmento de
stack
no está presente en el binario y contiene variables con duración de almacenamiento automático
Al eliminar el calificador const
de la variable main
hace que se mueva del text
al segmento de data
, que no es ejecutable, lo que provoca la violación de la segmentación que observa.
Las plataformas modernas a menudo tienen segmentos adicionales (por ejemplo, un segmento rodata
para datos que no se pueden escribir ni ejecutar), por lo que no tome esto como una descripción precisa de su plataforma sin consultar la documentación específica de la plataforma.
Por favor, comprenda que no hacer que main
una función generalmente es incorrecto, aunque técnicamente una plataforma podría permitir que main
se declare como variable, cf. ISO 9899: 2011 §5.1.2.2.1 ¶1, énfasis mío:
1 La función llamada al inicio del programa se llama
main
. La implementación no declara ningún prototipo para esta función. Se definirá con un tipo de retorno deint
y sin parámetros (...) o con dos parámetros (...) o equivalentes; o de alguna otra manera definida por la implementación.