Observez comment la valeur 195 correspond à la valeur ret
(retour de fonction) sur les compatibles 8086. Cette définition de main
se comporte donc comme si vous l'aviez défini comme int main() {}
lorsqu'il est exécuté.
Sur certaines plateformes, const
sont chargées dans une région de mémoire exécutable mais non inscriptible, tandis que les données mutables (c'est-à-dire celles qui ne sont pas qualifiées de "données de base") sont chargées dans une région de mémoire exécutable mais non inscriptible. const
) est chargé dans une région de la mémoire accessible en écriture mais non exécutable. Pour cette raison, le programme "fonctionne" lorsque vous déclarez main
como const
mais pas lorsque vous omettez le const
qualificatif.
Traditionnellement, les binaires contenaient trois segments :
- En
text
est (si l'architecture le permet) protégé en écriture et exécutable, et contient du code exécutable, des variables de statique durée de stockage qualifiée const
et les chaînes de caractères littéraux
- En
data
est inscriptible et ne peut être exécuté. Il contient des variables non qualifiées const
con statique durée de stockage et (au moment de l'exécution) les objets avec alloué durée de stockage
- En
bss
est similaire au segment data
mais est initialisé à zéro. Il contient des variables de statique durée de stockage non qualifiée const
qui ont été déclarées sans initialisateur
- En
stack
n'est pas présent dans le segment binaire et contient des variables avec automatique durée de stockage
Retrait de la const
de la variable main
le déplace de l'espace de travail de l text
à la data
qui n'est pas exécutable, ce qui provoque la violation de segmentation que vous observez.
Les plates-formes modernes comportent souvent des segments supplémentaires (par exemple un rodata
pour les données qui ne sont ni inscriptibles ni exécutables). Ne considérez donc pas ceci comme une description précise de votre plate-forme sans consulter la documentation spécifique à cette dernière.
Veuillez comprendre que le fait de ne pas faire main
une fonction est généralement incorrecte, bien que, techniquement, une plate-forme puisse permettre à une personne d'accéder à une fonction. main
pour être déclarée comme variable, cf. ISO 9899:2011 §5.1.2.2.1 ¶1, c'est moi qui souligne :
1 La fonction appelée au démarrage du programme s'appelle main
. L'implémentation ne déclare aucun prototype pour cette fonction. Elle doit être définie avec un type de retour de int
et sans paramètres (...) ou avec deux paramètres (...) ou équivalent ; ou d'une autre manière définie par l'implémentation.