¿Por qué const int main = 195 resulta en un programa de trabajo pero sin el const termina en un fallo de segmentación?
Considere seguir el programa C (vea la demostración en vivo aquí).
const int main = 195;
Sé que en el mundo real ningún programador escribe código como este, porque no tiene ningún propósito útil y no tiene ningún sentido. Pero cuando elimino la palabra clave const
de arriba del programa, inmediatamente resulta 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: 'principal' suele ser un función [- Wmain]
const int main = 195; ^
¿Por qué la presencia y ausencia de la palabra clave const
hacen una diferencia aquí en el comportamiento del programa?
2 answers
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 lo definiera como int main() {}
cuando se ejecuta.
En algunas plataformas, const
los datos se cargan en una región de memoria ejecutable pero no ejecutable, mientras que los datos mutables (es decir, datos no calificados const
) se cargan en una región de memoria ejecutable pero no ejecutable. Por esta razón, el programa "funciona" cuando se declara main
como const
pero no cuando omites el calificador const
.
Tradicionalmente, los binarios contenían tres segmentos:
- El segmento
text
es (si está soportado por la arquitectura) protegido contra escritura y ejecutable, y contiene código ejecutable, variables de estática duración de almacenamiento calificadaconst
, y literales de cadena - El segmento
data
es escribible y no se puede ejecutar. Contiene variables no calificadasconst
con estática duración de almacenamiento y (en runtime) objects with allocated storage duration - El segmento
bss
es similar al segmentodata
pero se inicializa a todos los ceros. Contiene variables de estática duración de almacenamiento no calificadaconst
que han sido declaradas sin inicializador - El segmento
stack
no está presente en el binario y contiene variables con automático duración de almacenamiento
Eliminar el calificador const
de la variable main
lo hace para ser movido del segmento text
al segmento data
, que no es ejecutable, causando la violación de 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), así 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 main
una función suele ser 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 equivalente; o de alguna otra manera definida por la implementación.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-24 15:20:55
En C, main
en el ámbito global es casi siempre una función.
Usar main
como variable en el ámbito global hace que el comportamiento del programa sea indefinido.
(Simplemente podría ser que cuando escribes const
el compilador optimiza la variable a una constante y así tu comportamiento del programa es diferente. Pero el comportamiento del programa es todavía indefinido).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-23 15:14:49