136 votes

Main() est vraiment démarrer d’un programme C++ ?

La section $3.6.1/1 de la Norme C++ lit,

Un programme doit contenir un mondial fonction appelée principal, qui est le désigné début du programme.

Considérons maintenant ce code,

int square(int i) { return i*i; }
int user_main()
{ 
    for ( int i = 0 ; i < 10 ; ++i )
           std::cout << square(i) << endl;
    return 0;
}
int main_ret= user_main();
int main() 
{
        return main_ret;
}

Cet exemple de code fait ce que j'ai l'intention de faire, je.e l'impression de les carrés des entiers de 0 à 9, avant d'entrer dans l' main() fonction qui est censé être le "début" du programme.

Jetez un oeil à la sortie de ici : http://www.ideone.com/Niy0R

J'ai également compilé avec -pedantic option, GCC 4.5.0. Il ne donne aucune erreur, même pas attention!

Donc ma question est,

Est-ce code vraiment Standard conforme?

Si c'est standard conforme, alors n'est-il pas de nature à infirmer ce que dit la Norme? main() n'est pas le début de ce programme de! user_main() exécutée avant l' main().

Je comprends que pour initialiser la variable globale main_ret, use_main() s'exécute en premier, mais c'est complètement autre chose; le fait est que, il ne invalider la cité instruction $3.6.1/1 de la Norme, main() n'est PAS le début du programme; c'est en fait la fin de ce programme de!


EDIT:

Comment définissez-vous le mot "démarrer"?

Il se résume à la définition de l'expression "début du programme". Alors, comment exactement ne vous le définir?

92voto

Adam Davis Points 47683

Vous êtes la lecture de la phrase incorrecte.

Un programme doit contenir une fonction globale appelée principal, qui est le départ du programme.

La norme est de DÉFINIR le mot "start" pour les besoins du reste de la série. Cela ne veut pas dire que le code ne s'exécute avant main est appelé. Il est dit que le début du programme est considéré comme étant à la fonction main.

Votre programme est conforme. Votre programme n'a pas "commencé" jusqu'principal est commencé. Le constructeur est appelé avant que votre programme "commence", selon la définition de "démarrer" dans la norme, mais que peu de questions. BEAUCOUP de code est exécutée avant l' main est jamais appelé dans chaque programme, pas seulement pour cet exemple.

Pour les fins de la discussion, votre constructeur de code est exécuté avant le "début" du programme, et qui est entièrement conforme à la norme.

87voto

Edwin Buck Points 33097

Non, C++ fait beaucoup de choses à "l'environnement", avant de procéder à l'appel du principal; toutefois, le principal est le début officiel de la "utilisateur spécifié" une partie du programme en C++.

Certains de la configuration de l'environnement n'est pas contrôlable (comme le code initial pour définir std::cout; cependant, certains de l'environnement est contrôlable comme statique global des blocs (pour l'initialisation statique des variables globales). Noter que, puisque vous n'avez pas le plein contrôle préalable de main, vous n'avez pas le plein contrôle sur l'ordre dans lequel les blocs statiques de l'initialisation.

Après la principale, votre code est conceptuellement "contrôle" du programme, dans le sens que vous pouvez spécifier les instructions à exécuter et l'ordre dans lequel les effectuer. Le Multi-threading pouvez réorganiser l'exécution de code à l'ordre; mais, vous êtes toujours en contrôle avec le C++ parce que vous avez spécifié d'avoir des sections de code à exécuter (peut-être) out-of-order.

25voto

CashCow Points 18388

Votre programme ne sera pas de lien et donc de ne pas s'exécuter que si il y a un principal. Cependant main() ne cause pas le début de l'exécution du programme, car les objets au niveau des fichiers ont les constructeurs qui s'exécutent à l'avance et il serait possible d'écrire un programme qui s'exécute de sa durée de vie avant le main() est atteint et laissez principale elle-même avoir un corps est vide.

En réalité, à appliquer à cette question, vous devez avoir un objet qui est construit avant le principal et de son constructeur à appeler tous les flux du programme.

Regardez ceci:

class Foo
{
public:
   Foo();

 // other stuff
};

Foo foo;

int main()
{
}

Le flux de votre programme serait effectivement proviennent Foo::Foo()

16voto

Remo.D Points 9841

Vous tagged la question "C", puis, en parlant strictement sur C, l'initialisation échoue conformément à l'article 6.7.8 "Initialisation" de la norme ISO C99.

Le plus pertinent dans ce cas semble être contrainte n ° 4 qui dit:

Toutes les expressions dans un initialiseur d'un objet qui a statique de la durée de stockage doit être des expressions constantes ou des littéraux de chaîne.

Donc, la réponse à votre question est que le code n'est pas conforme à la norme.

Vous auriez probablement souhaitez supprimer le "C" de la balise si vous étiez intéressé seulement par la norme C++.

11voto

aschepler Points 23731

Section 3.6 dans son ensemble est très clair sur l’interaction entre les et les initialisations dynamiques. Le début du programme « désigné » n’est pas utilisé n’importe où ailleurs et est simplement descriptif de l’esprit de . Il ne fait aucun sens d’interpréter cette un expression de manière normative qui est en contradiction avec les exigences plus claires et détaillées dans la norme.

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