Est-il légal de rentrer dans main () en C ++?

J’ai lu que le standard C ++ interdit la récursivité dans main() , mais g ++ comstack le code suivant sans se plaindre:

 int main() { main(); } 

Quelqu’un peut-il clarifier cela?

Selon la norme en 3.6.1 / 3, ce n’est pas:

La fonction main ne doit pas être utilisée (3.2) dans un programme

La définition de être utilisé est:

Un object ou une fonction non surchargée est utilisé si son nom apparaît dans une expression potentiellement évaluée .

Je vais faire le poisson et expliquer pourquoi c’est verboten . Avant qu’un programme C ou C ++ puisse démarrer, le CRT doit être initialisé en premier. Ouvrez stdin / out / err, appelez les initialiseurs, ce genre de chose. Il existe deux stratégies de base pour y parvenir, un détail lourd de mise en œuvre de la plate-forme.

  • L’adresse de démarrage du programme pointe vers la fonction d’initialisation CRT, qui appelle éventuellement main (). Commun sur les systèmes d’exploitation complets disposant d’un chargeur sophistiqué pouvant prendre en charge des sections arbitraires dans l’image exécutable.

  • Le compilateur injecte du code dans la fonction main () qui appelle la fonction d’initialisation CRT. La fonction de démarrage est toujours main (). Commun sur les plates-formes embarquées avec des capacités de chargeur limitées. Récurer main () est maintenant un problème, le code de démarrage CRT sera appelé à nouveau avec un état de stack imprévisible.

L’affirmation ici est qu’il est en effet expressément interdit:

Eh bien, la norme stipule:

3.6.1.3
“La fonction main ne doit pas être utilisée dans un programme.”

5.2.2.9
“Les appels récursifs sont autorisés, sauf pour la fonction nommée main”

Vous pouvez bien sûr faire ceci:

 int main(int argc, char* argv[]) { return foo(argc, argv); } int foo(int argc, char* argv[]) { if (some_condition) { return foo(argc, argv); } return 0; } 

(Remarque: j’ai ajouté une clause de sortie. Je ne peux même pas hypothétiquement coder une récursion infinie, elle se répète sur moi.)

Ce n’est pas légal Lisez 3.6.1-3:

La fonction main ne doit pas être utilisée (3.2) dans un programme. Le lien (3.5) de main est défini par la mise en œuvre. Un programme qui déclare principal être en ligne ou statique est mal formé. Le nom principal n’est pas autrement réservé. [Exemple: les fonctions membres, les classes et les énumérations peuvent être appelées main, tout comme les entités des autres espaces de noms. ]

D’autres personnes ont abordé la partie relative aux normes. Cependant, je voudrais noter que g ++ (au moins 4.6.2) le rejettera si vous utilisez -pedantic-errors avec au moins une de ces erreurs (en fonction de main signature main ):

 error: ISO C++ forbids calling '::main' from within program [-pedantic] error: ISO C++ forbids taking address of function '::main' [-pedantic]