32 votes

Pourquoi le programme fonctionne-t-il avec const int main = 195 alors qu'il se termine par une erreur de segmentation sans const ?

Considérez le programme C suivant (voir la démonstration en direct) aquí ).

const int main = 195;

Je sais que dans le monde réel, aucun programmeur n'écrit un tel code, car il ne sert à rien et n'a aucun sens. Mais lorsque j'enlève le const depuis le haut du programme, il en résulte immédiatement un défaut de segmentation . Pourquoi ? Je suis impatient d'en connaître la raison.

GCC 4.8.2 donne l'avertissement suivant lors de la compilation.

warning : 'main' est généralement une fonction [-Wmain]

const int main = 195;
          ^

Pourquoi la présence ou l'absence de const Le mot-clé fait-il ici une différence dans le comportement du programme ?

60voto

FUZxxl Points 21462

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.

11voto

Bathsheba Points 23209

En C, main à l'échelle mondiale est presque toujours une fonction.

Pour utiliser main en tant que variable globale rend le comportement du programme indéfini.

(Il s'agit juste puede il se peut que lorsque vous écrivez const le compilateur optimise la variable en une constante, ce qui modifie le comportement du programme. Mais le comportement du programme est encore non défini).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X