71 votes

La fonction main() est-elle surchargée en C++ ?

2 versions valides de main() existent dans C++ :

int main()  // version 1
int main(int argc, char **argv)  // version 2

Mais les deux surcharges ne peuvent coexister en même temps. Pourquoi pas ? (Cas d'utilisation potentiel : lors de l'exécution du programme à partir du terminal, si aucun argument n'est passé, la première version est appelée, sinon la seconde).

Le compilateur effectue-t-il une vérification spéciale pour n'autoriser qu'une seule version par binaire ?

67voto

Nawaz Points 148870

§3.6.1/2 (C++03) dit

Une mise en œuvre ne doit pas prédéfinir l' main fonction. Cette fonction est de ne pas être surchargé. Il doit avoir une le type de retour de type int, mais sinon son type est la mise en œuvre définies. Toutes les mises en œuvre doivent permettre à la fois les définitions suivantes de la principale:

   int main() { /* ... */ }
   int main(int argc, char* argv[]) { /* ... */ }

Vous pouvez utiliser l'un ou l'autre. Les deux sont conformes à la norme.

Aussi, depuis char *argv[] est équivalent à char **argv, en remplaçant char *argv[] avec char **argv ne fait aucune différence.


Mais les deux versions ne peuvent pas co-exister au même moment ! (cas d'utilisation peut être: pendant l'exécution du binaire à partir de l'invite de commande, si vous ne transmettez pas d'argument alors 1ère version devrait être appelé d'autre de la 2ème version).

Pas de. Les deux versions ne peuvent pas co-exister au même moment. Un programme peut avoir exactement un main fonction. Qui, dépend de votre choix. Si vous voulez traiter de l'argument de ligne de commande, alors vous avez à choisir la deuxième version, ou bien de la première version est assez. Notez également que si vous utilisez la deuxième version, et ne pas passer aucun argument de ligne de commande, alors il n'y a rien de mal. Il ne provoque pas d'erreur. Vous avez juste à interpréter argc et argv en conséquence, et sur la base de leur valeur, vous avez à écrire la logique et le déroulement de votre programme.

20voto

Skizz Points 30682

Windows et Unix en ont :

int main(int argc, char **argv, char **envp)

et les applications Win32 ont :

int WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);

et MacOS a :

int main(int argc, char **argv, char **envp, char **apple)

N'oubliez pas que main n'est généralement pas la première chose que le système d'exploitation appelle lors de l'exécution d'un programme. Le site main est la fonction qui est appelée par l'environnement d'exécution. L'adresse de la première instruction à exécuter est généralement déclarée dans des métadonnées, en général au début du fichier exécutable.

Pour autant que je sache, rien de ce qui précède ne contredit le standard C/C++, tant qu'il n'y en a qu'un seul, ce qui est logique puisque le système d'exploitation ne saurait pas lequel appeler s'il y en avait plusieurs. Vérifier qu'il n'y en a qu'un seul n'est pas fait dans le compilateur, mais dans l'éditeur de liens.

13voto

Alok Save Points 115848

Section 3.6.1.2 des états C++ Standard 1998 et 2003 :

Une implémentation ne doit pas prédéfinir la fonction principale. Cette fonction ne doit pas être surchargée . Il doit avoir un type de retour de type int, mais sinon son type est défini par l'implémentation.

Plus loin,

La norme ISO C++ (ISO/IEC 14882:1998) exige spécifiquement que main renvoie int. Il s'agit d'une contrainte explicite "shall" pour les programmes bien formés.

Section § 3.6.1 ¶ 2 :

Il doit avoir un type de retour de type int, mais sinon son type est défini par l'implémentation. Toutes les implémentations doivent permettre les deux définitions suivantes de main :

int main() { /* … */ }

et

int main(int argc, char* argv[]) { /* … */ }

Ainsi, les deux versions de main sont autorisées par la norme et le choix de l'une d'entre elles est laissé à la préférence du programmeur.

9voto

Billy ONeal Points 50631

Main a été définie à l'époque du C. Il est configuré plus selon les règles de printf. Considérons main comme une fonction varadique :

int main(...)

La norme stipule qu'aucun argument et deux arguments de type pointeur sont acceptables. Cependant, si l'implémentation veut fournir plus d'arguments, elle est libre de le faire.

La raison pour laquelle vous ne pouvez pas avoir deux main est la même raison pour laquelle vous ne pouvez pas définir une printf une fonction similaire deux fois dans un programme C. Bien sûr, printf supporte différents arguments et change son comportement en fonction des arguments présents, mais ce n'est pas une surcharge au sens C++ du terme.

7voto

peoro Points 12875

La norme stipule que main ne peut pas être surchargé. Il n'est pas mangé, et vous ne pouvez pas avoir deux fonctions avec le même nom non mangé. Cela provoquera un échec de liaison, je suppose, mais un compilateur pourrait vouloir ajouter des vérifications explicites afin de donner des messages d'erreur plus clairs.

int main(int argc, char **argv) y int main() devrait être la signature préférée, mais les compilateurs sont libres d'accepter une signature de type main avec différents paramètres.

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