155 votes

Quelle est la déclaration correcte de main en C++ ?

Questions

  • Quelle est la signature appropriée de la main en C++ ?

  • Quel est le type de retour correct, et qu'est-ce que cela signifie de retourner une valeur de main ?

  • Quels sont les types de paramètres autorisés, et quelle est leur signification ?

  • Est-ce spécifique au système ?

  • Ces règles ont-elles changé au fil du temps ?

  • Que se passe-t-il si je les enfreins ?

1 votes

C'est très proche de, ou un duplicata de, Qu'est-ce qui devrait main retour en C et C++ .

0 votes

@JonathanLeffler Sans blague... il a été ajouté à la liste des doublons en révision 6 il y a environ 8 mois.

200voto

James McNellis Points 193607

El main doit être déclarée comme une fonction non membre dans l'espace de noms global. Cela signifie qu'elle ne peut pas être une fonction membre statique ou non statique d'une classe, ni être placée dans un espace de noms (même l'espace de noms 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 y compris, entre autres, les classes, les variables, les énumérations, les fonctions membres et les fonctions non membres qui ne se trouvent 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 nom, mais une telle fonction ne serait pas la main qui désigne l'endroit où le programme commence.

El main ne peut pas être déclarée comme static o inline . Elle ne peut pas non plus être surchargée ; il ne peut y avoir qu'une seule fonction nommée main dans l'espace de nom global.

El 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 courant de voir des programmes incorrects qui déclarent main avec un type de retour de void ; il s'agit probablement de la règle la plus fréquemment violée concernant la main fonction).

Il existe deux déclarations de main qui doivent être autorisés :

int main()               // (1)
int main(int, char*[])   // (2)

En (1) il n'y a pas de paramètres.

En (2) il y a deux paramètres et ils sont nommés par convention argc y 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 argv le tableau.

Habituellement, argv[0] contient le nom du programme, mais ce n'est pas toujours le cas. argv[argc] est garanti comme étant un pointeur nul.

Notez que puisqu'un argument de type tableau (comme char*[] ) n'est en fait qu'un argument de type pointeur déguisé, les deux façons suivantes sont toutes deux valables pour é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 paramètres ; vous devez consulter la documentation de votre implémentation pour savoir ce qu'elle prend en charge.

main() est censé renvoyer zéro pour indiquer un succès et une valeur différente de zéro pour indiquer un échec. Vous n'êtes pas obligé d'écrire explicitement un return déclaration dans main() : si vous laissez main() sans un retour explicite return c'est la même chose que si vous aviez écrit return 0; . Les deux suivants main() ont le même comportement :

int main() { }
int main() { return 0; }

Il existe deux macros, EXIT_SUCCESS y EXIT_FAILURE défini dans <cstdlib> qui peut également être renvoyé par main() pour indiquer le succès et l'échec, respectivement.

La valeur renvoyée par main() est transmis à la exit() qui met fin au programme.

Notez que tout ceci ne s'applique que lors de la compilation pour un environnement hébergé (de manière informelle, un environnement où vous disposez d'une bibliothèque standard complète et où un système d'exploitation exécute votre programme). Il est également possible de compiler un programme C++ pour un environnement autonome (par exemple, certains types de systèmes embarqués), auquel cas le démarrage et la fin sont entièrement définis par l'implémentation et une fonction main() n'est peut-être même pas nécessaire. Cependant, si vous écrivez du C++ pour un système d'exploitation de bureau moderne, vous compilez pour un environnement hébergé.

1 votes

IIRC les seules valeurs de retour garanties sont 0, EXIT_SUCCESS (même effet que 0), et EXIT_FAILURE. EDIT : Ah, OK, d'autres valeurs d'état non nulles peuvent être retournées, mais avec une signification définie par l'implémentation. Seul EXIT_FAILURE est garanti d'être interprété d'une certaine manière comme une valeur d'échec.

0 votes

Il ne serait pas mal de préciser (juste pour être sûr) que cela fait référence à C++. Les utilisateurs de Java/C# peuvent être déroutés car ces langages sont en réalité exiger le point d'entrée à - contre-intuitivement - être dans une classe (pour une raison quelconque). De plus, l'ancien void main le format est un vestige de C ?

4 votes

@Synetech : La question demande dans sa première phrase, "Quelle est la signature appropriée de la fonction principale en C++ ?" et la question est étiquetée à la fois [c++] et [c++-faq]. Je ne peux rien faire si les utilisateurs de Java ou de C# (ou toute autre personne) sont encore confus. Le C# exige Main pour être une fonction membre statique car il n'a même pas de fonctions non membres. Même C89 exige main pour revenir int . Je ne suis pas suffisamment familier avec K&R C pour connaître ses règles exactes, mais je suppose qu'il exige également main pour revenir int depuis main sans type de retour était assez courant et pas de type = implicite int dans K&R.

15voto

liaK Points 6045

De la documentation standard.., 3.6.1.2 Fonction principale ,

Il doit avoir un 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 définitions de main :

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

Dans cette dernière forme argc est le nombre d'arguments passés au programme de l'environnement dans lequel le programme est exécuté. programme est exécuté. Si argc est différent de zéro ces arguments doivent être fournis dans argv[0] à argv[argc-1] comme pointeurs sur les caractères initiaux des chaînes multi-octets à terminaison nulle. .....

J'espère que cela vous aidera

2 votes

Existe-t-il une raison spécifique pour laquelle le type de retour de l'option main devrait être int ?

1 votes

@SuhailGupta : Pour que le processus appelant sache si este Le processus doit être considéré comme réussi ou non. Permettre à void casse ce modèle. Cela n'a même pas vraiment de sens si vous le faites signifier "toujours considérer le succès". Parce que vous n'aviez aucun moyen de dire si le processus avait réellement échoué, alors vous avez vraiment réussir ? Non, retour int .

4voto

Matt McNabb Points 14273

Le libellé exact de la dernière norme publiée (C++14) est le suivant :

Une implémentation doit permettre à la fois

  • en fonction de () en retournant sur int et

  • en fonction de (int , pointeur vers pointeur vers char) en retournant sur int

comme le type de main .

Cela indique clairement que les orthographes alternatives sont autorisées tant que le type de main est le type int() o int(int, char**) . Les éléments suivants sont donc également autorisés :

  • int main(void)
  • auto main() -> int
  • int main ( )
  • signed int main()
  • typedef char **a; typedef int b, e; e main(b d, a c)

3voto

stonemetal Points 4734

Les deux secteurs valables sont int main() y int main(int, char*[]) . Toute autre chose peut ou ne peut pas compiler. Si main ne renvoie pas explicitement une valeur, 0 est implicitement retourné.

1 votes

Je n'ai jamais vu de code ne pas être compilé quand je mentionne le type de retour de main pour être nulle. Y a-t-il une raison spécifique pour que le type de retour de main soit int ?

4 votes

La spécification du langage indique que main doit avoir un type de retour int. Tout autre type de retour autorisé par votre compilateur est une amélioration spécifique au compilateur. En fait, l'utilisation de void signifie que vous programmez dans un langage similaire à C++, mais pas dans ce langage.

2 votes

La raison pour laquelle la norme exige un int comme type de retour de main est que cette valeur est transmise à l'interpréteur de commandes en tant que code de sortie du programme. sh attend un int .

2voto

Ben Voigt Points 151460

Détails sur les valeurs de retour et leur signification

Par 3.6.1 ( [basic.start.main] ) :

Une instruction de retour dans main a pour effet de laisser le main (en détruisant tous les objets ayant une durée de stockage automatique) et en appelant la fonction std::exit avec la valeur de retour comme argument. Si le contrôle atteint la fin de main sans rencontrer un return l'effet est celui de l'exécution de

return 0;

Le comportement de std::exit est détaillée 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 de l'état "successful termination" est retournée. Si le statut est EXIT_FAILURE une forme définie par l'implémentation de l'état unsuccessful termination est renvoyée. Sinon, l'état renvoyé est défini par l'implémentation.

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