Est-ce que main () est surchargé en C ++?

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

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

Mais les deux surcharges ne peuvent pas 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 transmis, la première version est appelée, sinon la deuxième version est.)

Le compilateur effectue-t-il une vérification spéciale pour autoriser une seule version par binary?

§3.6.1 / 2 (C ++ 03) dit

Une mise en œuvre ne doit pas prédéfinir la fonction main . 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. Toutes les implémentations doivent autoriser les deux définitions suivantes de main:

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

Vous pouvez utiliser l’un ou l’autre. Les deux sont conformes aux normes.

De plus, puisque char *argv[] est équivalent à char **argv , remplacer char *argv[] par char **argv ne fait aucune différence.


Mais les deux versions ne peuvent pas coexister en même temps! (le cas d’utilisation peut être le suivant: lors de l’exécution de l’invite de commande binary, si vous ne transmettez aucun argument, la 1ère version doit être appelée la 2ème version).

Non, les deux versions ne peuvent pas coexister en même temps. Un programme peut avoir exactement une fonction main . Lequel, dépend de votre choix. Si vous voulez traiter un argument de ligne de commande, vous devez choisir la deuxième version, sinon la première version suffit. Notez également que si vous utilisez la deuxième version et que vous ne passez aucun argument de ligne de commande, alors il n’y a pas de problème. Cela ne causera aucune erreur. Vous devez juste interpréter argc et argv conséquence, et en fonction de leur valeur, vous devez écrire la logique et le stream de votre programme.

Windows et Unix 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. La fonction main est la fonction 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 certaines métadonnées, généralement au début si le fichier exécutable.

Rien de ce qui précède ne contredit le standard C / C ++, pour autant que je sache, tant qu’il n’y en a qu’un, ce qui est logique puisque le système d’exploitation ne sait pas qui appeler s’il y en a plusieurs. Vérifier qu’il n’y en a qu’un n’est pas fait dans le compilateur, cela se fait dans l’éditeur de liens.

La section 3.6.1.2 des éditions C ++ Standard 1998 et 2003 indique:

Une mise en œuvre 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 to return int. Il a une contrainte explicite “doit” sur les programmes bien formés.

Section § 3.6.1 ¶ 2:

Il doit avoir un type de retour int, mais sinon son type est défini par l’implémentation. Toutes les implémentations doivent autoriser 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 celle à utiliser est laissée comme préférence d’implémentation du programmeur.

Main a été défini dans les jours C. C’est plus configuré selon les règles de printf. Considérez main comme une fonction varadique:

 int main(...) 

La norme dit qu’aucun argument et deux arguments de pointeur ne sont acceptables. Cependant, si l’implémentation souhaite fournir plus d’arguments, la mise en œuvre est libre de le faire.

La raison pour laquelle vous ne pouvez pas avoir deux fonctions main est la même raison pour laquelle vous ne pouvez pas définir une fonction printf like à deux resockets dans un programme C. Bien sûr, printf prend en charge différents arguments et modifie son comportement en fonction des arguments présents, mais il ne se surcharge pas au sens C ++ du terme.

La norme dit que le main ne peut pas être surchargé. Il n’est pas mutilé, et vous ne pouvez pas avoir deux fonctions avec le même nom non modifié. Je suppose que cela provoquerait un échec de la liaison, mais un compilateur pourrait vouloir append des vérifications explicites pour donner des messages d’erreur plus clairs.

int main(int argc, char **argv) et int main() devraient être les signatures préférées pour cela, mais les compilateurs sont libres d’accepter une main avec des parameters différents.

Il n’est pas possible de surcharger main () en C ++ car. le compilateur a montré l’erreur suivante:

 error C2731: 'main' : function cannot be overloaded