Quelle est la signature correcte de la fonction main
en C ++? Quel est le type de retour correct et qu’est-ce que cela signifie de renvoyer une valeur de main
? Quels sont les types de parameters autorisés et quelles sont leurs significations?
Est-ce spécifique au système? Ces règles ont-elles changé avec le temps? Que se passe-t-il si je les viole?
La fonction main
doit être déclarée comme une fonction non membre dans l’espace de noms global. Cela signifie qu’il ne peut pas être une fonction membre statique ou non statique d’une classe, ni être placé dans un espace de nommage (même dans l’espace de nommage sans nom).
Le nom main
n’est pas réservé en C ++ sauf en tant que fonction dans l’espace de noms global. Vous êtes libre de déclarer d’autres entités nommées main
, notamment des classes, des variables, des énumérations, des fonctions membres et des fonctions non membres qui ne figurent pas dans l’espace de noms global.
Vous pouvez déclarer une fonction nommée main
comme une fonction membre ou dans un espace de nommage, mais une telle fonction ne serait pas la fonction main
qui désigne où le programme démarre.
La fonction main
ne peut pas être déclarée comme static
ou en inline
. Il ne peut pas non plus être surchargé; il ne peut y avoir qu’une seule fonction nommée main
dans l’espace de noms global.
La fonction main
ne peut pas être utilisée dans votre programme: vous n’êtes pas autorisé à appeler la fonction main
de n’importe où dans votre code, et vous n’êtes pas autorisé à prendre son adresse.
Le type de retour de main
doit être int
. Aucun autre type de retour n’est autorisé (cette règle est en gras car il est très fréquent de voir des programmes incorrects déclarant main
avec un type de retour void
; c’est probablement la règle la plus fréquemment violée concernant la fonction main
).
Il y a deux déclarations de main
qui doivent être autorisées:
int main() // (1) int main(int, char*[]) // (2)
En (1) , il n’y a pas de parameters.
Dans (2) , il y a deux parameters et ils sont nommés conventionnellement argc
et argv
, respectivement. argv
est un pointeur vers un tableau de chaînes C représentant les arguments du programme. argc
est le nombre d’arguments dans le tableau argv
.
En général, argv[0]
contient le nom du programme, mais ce n’est pas toujours le cas. argv[argc]
est garanti pour être un pointeur nul.
Notez que comme un argument de type tableau (comme char*[]
) n’est en réalité qu’un argument de type pointeur déguisé, les deux suivants sont tous deux des moyens valables d’écrire (2) et ils signifient tous deux exactement la même chose:
int main(int argc, char* argv[]) int main(int argc, char** argv)
Certaines implémentations peuvent autoriser d’autres types et nombres de parameters; vous devez vérifier la documentation de votre implémentation pour voir ce qu’elle prend en charge.
main()
devrait renvoyer zéro pour indiquer le succès et non-zéro pour indiquer un échec. Vous n’êtes pas obligé d’écrire explicitement une déclaration de return
dans main()
: si vous laissez main()
retourner sans une déclaration de return
explicite, c’est comme si vous aviez écrit return 0;
. Les deux fonctions main()
suivantes ont le même comportement:
int main() { } int main() { return 0; }
Il existe deux macros, EXIT_SUCCESS
et EXIT_FAILURE
, définies dans
qui peuvent également être renvoyées par main()
pour indiquer respectivement le succès et l’échec.
La valeur renvoyée par main()
est transmise à la fonction exit()
, qui termine le programme.
Notez que tout cela s’applique uniquement lors de la compilation pour un environnement hébergé (de manière informelle, un environnement dans lequel vous avez une bibliothèque standard complète et un système d’exploitation exécutant votre programme). Il est également possible de comstackr un programme C ++ pour un environnement autonome (par exemple, certains types de systèmes intégrés), auquel cas le démarrage et la terminaison sont entièrement définis par l’implémentation et une fonction main()
peut même ne pas être requirejse. Si vous écrivez C ++ pour un OS de bureau moderne, vous comstackz pour un environnement hébergé.
De la documentation standard, 3.6.1.2 Fonction principale ,
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() { / ... / }
et int main(int argc, char* argv[]) { / ... / }
Dans cette dernière forme,
argc
sera le nombre d’arguments transmis au programme à partir de l’environnement dans lequel le programme est exécuté. Si argc est différent de zéro, ces arguments doivent être fournis dans argv [0] via argv [argc-1] caractères initiaux des chaînes multi-octets terminées par un caractère nul …..
J’espère que cela pourra aider..
La formulation exacte de la dernière norme publiée (C ++ 14) est la suivante:
Une mise en œuvre doit permettre à la fois
une fonction de
()
retournantint
etune fonction de
(int
, pointeur sur le pointeur verschar)
renvoyantint
comme type de
main
.
Cela montre clairement que d’autres orthographes sont permises tant que le type de main
est le type int()
ou int(int, char**)
. Donc, les éléments suivants sont également autorisés:
int main(void)
auto main() -> int
int main ( )
signed int main()
typedef char **a; typedef int b, e; e main(bd, ac)
Les deux secteurs principaux sont int main()
et int main(int, char*[])
. Toute autre chose peut ou non comstackr. Si main
ne retourne pas explicitement une valeur, 0 est retourné implicitement.
Détails sur les valeurs de retour et leur signification
Par 3.6.1 ( [basic.start.main]
):
Une déclaration de retour dans
main
a pour effet de laisser la fonctionmain
(détruire tout object avec une durée de stockage automatique) et d’appelerstd::exit
avec la valeur de retour comme argument. Si le contrôle atteint la fin demain
sans rencontrer de déclaration dereturn
, l’effet est d’exécuterreturn 0;
Le comportement de std::exit
est détaillé dans la section 18.5 ( [support.start.term]
) et décrit le code d’état:
Enfin, le contrôle est renvoyé à l’environnement hôte. Si le statut est zéro ou
EXIT_SUCCESS
, une forme définie par l’implémentation du statut de terminaison réussie est renvoyée. Si le statut estEXIT_FAILURE
, une forme définie par l’implémentation de la résiliation d’état infructueuse est renvoyée. Sinon, le statut renvoyé est défini par l’implémentation.