45 votes

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

J'ai lu que la norme C ++ interdit la récursivité dans main() , mais g ++ compile le code suivant sans aucun reproche:

 int main()
{
    main();
}
 

Quelqu'un peut-il clarifier cela?

50voto

icecrime Points 23650

Selon la norme de 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 utilisé étant:

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

37voto

Hans Passant Points 475940

Je vais faire le poisson et d'expliquer pourquoi c'est verboten. Avant qu'un programme C ou C++ peut commencer à courir, le CRT doit être initialisé en premier. Ouvrir stdin/out/err, appelez les initialiseurs, ce genre de chose. Il existe deux stratégies de base pour obtenir ce fait, une lourde plate-forme de mise en œuvre détail.

  • Le programme de l'adresse de démarrage des points pour la CGT fonction init, qui finalement l'appel à main(). Commun sur complète des systèmes d'exploitation qui ont une fantaisie chargeur qui peuvent favoriser l'arbitraire des sections dans le fichier exécutable de l'image.

  • Le compilateur injecte du code dans la fonction main() qui appelle la CGT fonction d'initialisation. La fonction de démarrage est toujours main(). Commun sur les plateformes embarquées avec peu de chargeur de capacités. Recursing main() est maintenant un problème, le code de démarrage du CRT sera appelée de nouveau avec un imprévisible de l'état de la pile.

22voto

T.J. Crowder Points 285826

La demande ici , c'est qu'il est en effet expressément interdit:

Ainsi, la norme précise:

3.6.1.3
"La fonction principale ne doit pas être utilisé à l'intérieur d'un programme."

5.2.2.9
"Les appels récursifs sont autorisés, à l'exception de 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 code de récursivité infinie, elle se répète sur moi.)

9voto

BЈовић Points 28674

Ce n'est pas légal. Lire 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 oeuvre. Un programme qui déclare que main est en ligne ou statique est mal formé. Le nom principal n'est pas réservé autrement. [Exemple: les fonctions membres, les classes et les énumérations peuvent être appelées main, de même que les entités situées dans d'autres espaces de noms. ]

1voto

Matthew Flaschen Points 131723

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

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

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