Qu'est-ce que main() devrait retourner en C et c++?

18 réponses

la valeur de retour de main devrait indiquer comment le programme a quitté. La sortie normale est généralement représentée par une valeur de retour 0 de main . La terminaison anormale est habituellement signalée par un retour non nul, mais il n'y a pas de norme pour l'interprétation des codes non nuls. Comme d'autres l'ont noté, void main() est explicitement interdit par la norme C++ et ne devrait pas être utilisé. Les signatures valides C++ main sont:

int main()

et

int main(int argc, char* argv[])

qui est l'équivalent de

int main(int argc, char** argv)

il est aussi intéressant de noter que dans C++, int main() peut être laissé sans valeur de retour à laquelle il renvoie 0 par défaut. Cela est également vrai dans le cas d'un programme C99. La question de savoir si le retour 0 doit être omis ou non est discutable. Le nombre de signatures valides pour le programme C est beaucoup plus élevé.

en outre, l'efficacité n'est pas un problème avec la fonction main . Il ne peut être entré et laissé qu'une seule fois (en marquant le début et la fin du programme) selon la norme C++. Pour C, le cas est différent et la réimpression de main() est autorisée, mais devrait probablement être évitée.

478
répondu workmad3 2018-01-22 13:49:38

la réponse acceptée semble être ciblée Pour C++, donc j'ai pensé que je pourrais ajouter une réponse qui se rapporte à C, et cela diffère à quelques égards.

ISO / CEI 9899: 1989 (C90):

main() doit être déclaré comme suit:

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

ou l'équivalent. Par exemple, int main(int argc, char *argv[]) est équivalent à la seconde. De plus, le type de retour int peut être omis car il s'agit d'un défaut.

si une mise en œuvre le permet, main() peut être déclaré d'une autre manière, mais cela rend la mise en œuvre du programme définie, et plus strictement conforme.

la norme définit trois valeurs de retour qui sont strictement conformes (c'est-à-dire qui ne dépendent pas d'un comportement défini par la mise en œuvre): 0 et EXIT_SUCCESS pour une fin réussie, et EXIT_FAILURE pour une fin non réussie. Toutes les autres valeurs sont non standard et la mise en œuvre définies. main() doit avoir une mention explicite return à la fin pour éviter un comportement non défini.

enfin, il n'y a rien de mal, du point de vue des normes, à appeler main() d'un programme.

ISO / CEI 9899: 1999 (C99):

pour C99, tout est comme ci-dessus sauf:

  • le type de retour int ne peut être omis.
  • vous pouvez omettre la déclaration de retour de main() . Si vous le faites, et main() terminé, il ya un implicite return 0 .
140
répondu Chris 2017-08-05 17:45:56

Standard C - Environnement Hébergé

pour un environnement hébergé (c'est normal), la norme C11 (ISO / IEC 9899: 2011) dit:

5.1.2.2.1 démarrage du programme

la fonction appelée au démarrage du programme s'appelle main . La mise en œuvre déclare non prototype pour cette fonction. Il doit être défini avec un type de retour int et sans paramètre:

int main(void) { /* ... */ }

ou avec deux paramètres (appelés ici argc et argv , bien que n'importe quel nom puisse être utilisé, car ils sont locaux à la fonction dans laquelle ils sont déclarés):

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

ou l'équivalent; 10) ou d'une autre manière définie par la mise en œuvre.

S'ils sont déclarés, les paramètres de la fonction principale doivent obéir aux règles suivantes: contraintes:

  • la valeur de argc doit être non négative.
  • argv[argc] doit être un pointeur nul.
  • si la valeur de argc est supérieure à zéro, les membres du tableau argv[0] par argv[argc-1] inclusive doit contenir des pointeurs vers des chaînes, qui sont donnés implémentation-valeurs définies par l'environnement hôte avant le démarrage du programme. Le l'intention est de fournir à l'information de programme déterminée avant le démarrage du programme d'ailleurs dans l'environnement hébergé. Si l'environnement hôte n'est pas capable de fournir des chaînes avec des lettres en majuscules et en minuscules, la mise en œuvre doit s'assurer que les cordes sont reçues en minuscules.
  • Si la valeur de argc est supérieure à zéro, la chaîne pointée par argv[0] représente le nom du programme; argv[0][0] est le caractère null si le le nom du programme n'est pas disponible dans l'environnement d'accueil. Si la valeur de argc est plus grand qu'un, les cordes pointées par argv[1] à argv[argc-1] représentent les paramètres du programme.
  • paramètres argc et argv et les chaînes pointées par le argv tableau sont être modifiables par le programme, et conserver leurs dernières valeurs stockées entre les programmes démarrage et fin du programme.

10) ainsi, int peut être remplacé par un nom typéf défini comme int , ou le type de argv peut être écrit comme char **argv , et ainsi de suite.

de fin de Programme en C99 ou C11

la valeur retournée de main() est transmise à l '"environnement" d'une manière définie par la mise en œuvre.

5.1.2.2.3 fin du programme

1 si le type de retour de la fonction main est un type compatible avec int , un retour l'appel initial à la fonction main est équivalent à l'appel de la fonction exit avec la valeur renvoyé par la fonction main comme son argument; 11) atteindre le } qui met fin à la main renvoie une valeur de 0. Si le type de retour n'est pas compatible avec int , le le statut de résiliation retourné à l'environnement hôte n'est pas spécifié.

11) conformément au 6.2.4, les durées de vie des objets avec une durée de stockage automatique déclarée en main terminée dans le premier cas, même là où ils n'auraient pas dans le second.

notez que 0 est obligatoire en tant que "succès". Vous pouvez utiliser EXIT_FAILURE et EXIT_SUCCESS à partir de <stdlib.h> si vous préférez, mais 0 est bien établi, et est donc 1. Voir aussi codes de sortie supérieurs à 255 - possible? .

dans C89 (et donc dans Microsoft C), il n'y a pas de déclaration sur ce qui se passe si la fonction main() retourne mais ne spécifie pas de valeur de retour; elle conduit donc à un comportement non défini.

7.22.4.4 le exit fonction

¶5 Enfin, le contrôle est retourné à l'environnement hôte. Si la valeur de status est zéro ou EXIT_SUCCESS , une forme définie par la mise en œuvre du statut terminaison réussie est retournée. Si la valeur de status est EXIT_FAILURE , une forme définie par la mise en œuvre du statut terminaison infructueuse est retournée. Sinon, le statut retourné est défini par l'implémentation.

Standard C++ Environnement Hébergé

la norme C++11 (ISO / IEC 14882: 2011) dit:

3.6.1 fonction principale [fonction de base.commencer.main]

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

¶2 Une mise en œuvre ne doit pas précéder la fonction principale. Ce la fonction ne doit pas être surchargé. Il est avoir un type de retour de type int, mais sinon son type est implémentation définie. Toutes les implémentations doit permettre les deux définitions suivantes de main:

int main() { /* ... */ }

et

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

sous cette dernière forme argc doit être le nombre d'arguments transmis au programme par l'environnement dans lequel le programme est exécuté. Si argc est non nul ces arguments doit être fourni en argv[0] par argv[argc-1] comme pointeurs vers les caractères initiaux des chaînes multi-octets à terminaison nulle (NTMBSs) (17.5.2.1.4.2) et argv[0] doit être le pointeur vers le caractère initial D'une NTMBS qui représente nom utilisé pour invoquer le programme ou "" . La valeur de argc doit être non négative. La valeur de argv[argc] doit être 0. [ Note: il est recommandé d'ajouter tout autre paramètre (facultatif) après argv . -fin note ]

¶3 la fonction main ne doit pas être utilisée dans un programme. Le lien (3.5) de main est défini par la mise en œuvre. [...]

¶5 Une déclaration dans le corps du texte a pour effet de quitter la fonction principale (détruire tout objet avec une durée de stockage) et appelant std::exit avec la valeur de retour comme argument. Si le contrôle atteint la fin de main sans rencontrer de déclaration de retour, l'effet est celui de l'exécution

return 0;

la norme c++ dit explicitement "il [la fonction principale] doit avoir un type de retour de type int , mais sinon son type est implémentation définie", et nécessite les deux mêmes signatures que la norme C pour être pris en charge comme options. Ainsi, un ' void main ()' n'est pas directement autorisé par le standard c++, bien qu'il n'y ait rien qu'il puisse faire pour arrêter une implémentation non standard permettant des alternatives. Note ce c++ interdit à l'utilisateur d'appeler main (mais pas la norme C).

il y a un paragraphe de §18.5 Start and termination dans la norme C++11 qui est identique au paragraphe de §7.22.4.4 la exit fonction dans la norme C11 (citée ci-dessus), à l'exception d'une note de bas de page (qui documente simplement que EXIT_SUCCESS et EXIT_FAILURE sont définis dans <cstdlib> ).

Standard C-Common Extension

classiquement, les systèmes Unix supportent une troisième variante:

int main(int argc, char **argv, char **envp) { ... }

le troisième argument est une liste à terminaison nulle de pointeurs vers les chaînes, dont chacune est une variable d'environnement qui a un nom, un signe égal et une valeur (éventuellement vide). Si vous ne l'utilisez pas, vous pouvez toujours accéder à l'environnement via ' extern char **environ; ". Depuis longtemps, qui n'ont pas d'en-tête qui l'a déclaré, mais la norme POSIX 2008 exige maintenant qu'elle soit déclarée dans <unistd.h> .

ceci est reconnu par la norme C comme une extension courante, documentée à L'Annexe J:

J. 5.1 arguments D'environnement

¶1 Dans un environnement hébergé, la fonction principale reçoit un troisième argument, char *envp[] , qui pointe vers un tableau de pointeurs à terminaison nulle de char , chacun de qui pointe vers une corde qui fournit des informations sur l'environnement d'exécution du programme (5.1.2.2.1).

Microsoft C

le Microsoft VS 2010 compilateur est intéressant. Le site Web dit:

la syntaxe de la déclaration pour main est

 int main();

ou, facultativement,

int main(int argc, char *argv[], char *envp[]);

alternativement, les fonctions main et wmain peuvent être déclarées comme retournant void (aucune valeur de retour). Si vous déclarez que main ou wmain est nul, vous ne pouvez pas retourner un code de sortie au processus parent ou au système d'exploitation en utilisant un État de retour. Pour retourner un code de sortie lorsque main ou wmain est déclaré comme void , vous devez utiliser la fonction exit .

il est pas clair pour moi ce qui se passe (quel code de sortie est retourné au parent ou à L'OS) quand un programme avec void main() sort - et le site Web de MS est silencieux aussi.

fait intéressant, MS ne prescrit pas la version à deux arguments de main() que les normes C et C++ exigent. Il ne prescrit trois argument forme où le troisième argument est char **envp , un pointeur vers une liste de variables d'environnement.

la page Microsoft aussi liste d'autres alternatives - wmain() qui prend des chaînes de caractères larges, et plus encore.

Microsoft Visual Studio 2005 version de cette page ne pas inscrire void main() comme une alternative. Les versions de Microsoft Visual Studio 2008 à partir de faire.

Standard C - Autonome De L'Environnement

comme nous l'avons déjà mentionné, les exigences ci-dessus s'appliquent aux environnements hébergés. Si vous travaillez avec un environnement autonome (qui est l'alternative à un environnement hébergé), alors la norme a beaucoup moins à dire. Pour un environnement autonome, la fonction appelée au démarrage du programme n'a pas besoin d'être appelée main et il n'y a aucune contrainte sur son type de retour. La norme dit:

5.1.2 environnements D'exécution

deux environnements d'exécution sont définis: freestanding et hosted. Dans les deux cas, le démarrage du programme se produit quand une fonction C désignée est appelée par l'exécution environnement. Tous les objets avec une durée de stockage statique doivent être initialisés (mis à leurs valeurs initiales) avant le démarrage du programme. La manière et le moment de cette initialisation ne sont pas précisés. Fin de programme retourne le contrôle à l'environnement d'exécution.

5.1.2.1 Environnement autoportant

dans un environnement autonome (dans lequel L'exécution du programme C peut avoir lieu sans aucun avantage d'un système d'exploitation), le nom et le type de la fonction appelée au démarrage du programme sont implémentation-defined. Toute bibliothèque disponible pour un programme autonome, autre que l'ensemble minimal requis par l'article 4, est définie par la mise en œuvre.

L'effet de fin de programme dans un autoportant l'environnement est mise en œuvre définies.

le renvoi à la conformité à la clause 4 renvoie à ceci:

numéro 5 en se conformant strictement programme ne doit utiliser que les fonctionnalités de la langue et de la bibliothèque spécifiée dans la présente Norme Internationale. 3) il ne doit pas produire de sortie dépendant d'un comportement non spécifié, non défini, ou défini par la mise en œuvre, et ne doit pas dépasser une limite minimale de mise en œuvre.

¶6 les deux formes de mise en œuvre conforme sont hébergé et autonome . Un conforme mise en œuvre hébergée doit accepter tout programme strictement conforme. Un conforme autonomes de mise en œuvre doit accepter tout en se conformant strictement programme dans lequel l'utilisation des fonctions spécifiées dans la la clause de bibliothèque (clause 7) se limite au contenu des en-têtes standards <float.h> , <iso646.h> , <limits.h> , <stdalign.h> , <stdarg.h> , <stdbool.h> , <stddef.h> , <stdint.h> , et <stdnoreturn.h> . Une implémentation conforme peut avoir des extensions (y compris fonctions supplémentaires de la bibliothèque), à condition qu'ils ne modifient pas le comportement d'un programme strictement conforme. 4)

¶7 conforme le programme est un programme acceptable pour une mise en œuvre conforme. 5)

3) un programme strictement conforme peut utiliser des caractéristiques conditionnelles (voir 6.10.8.3) à condition que l'utilisation soit protégée par une directive appropriée de prétraitement d'inclusion conditionnelle utilisant la macro correspondante. Par exemple:

#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */
    /* ... */
    fesetround(FE_UPWARD);
    /* ... */
#endif

4) cela implique qu'une la mise en œuvre se réserve pas de désignations autres que celles qui sont explicitement réservés dans la présente Norme Internationale.

5) les programmes strictement conformes sont conçus pour être transférables au maximum parmi les implémentations conformes. Les programmes conformes peuvent dépendre des caractéristiques non portables d'une mise en œuvre conforme.

Il est notable que le seul en-tête requis d'un autoportant environnement en fait définit toutes les fonctions est <stdarg.h> (et même ceux peuvent être - et sont souvent - juste des macros).

Standard C++ - Autonome De L'Environnement

tout comme la norme C reconnaît à la fois l'environnement hébergé et l'environnement autonome, il en va de même de la norme C++. (Citations de ISO / IEC 14882: 2011.)

1.4 Mise en oeuvre conformité [intro.la conformité]

¶7 deux sortes de les implémentations sont définies: une implémentation hébergée et une implémentation autonome . Pour une mise en œuvre hébergée, cette norme internationale définit l'ensemble des bibliothèques disponibles. Un autoportant la mise en œuvre est une exécution qui peut avoir lieu sans le bénéfice d'un système d'exploitation, et a un ensemble de bibliothèques défini par la mise en œuvre qui inclut certaines bibliothèques de soutien linguistique (17.6.1.3).

¶8 une implémentation conforme peut avoir des extensions (y compris des fonctions supplémentaires de bibliothèque), à condition qu'elles ne modifient pas le comportement d'un programme bien formé. Les implémentations sont nécessaires pour diagnostiquer les programmes que utilisez de telles extensions qui sont mal formées selon cette norme internationale. Cela étant, ils peuvent compiler et exécuter de tels programmes.

¶9 chaque mise en œuvre doit comprendre des documents qui identifient tous les le support conditionnel construit qu'il ne supporte pas et ne définit pas toutes les caractéristiques locales spécifiques. 3

3) cette documentation définit également le comportement défini par la mise en œuvre; Voir 1.9.

17.6.1.3 mises en œuvre autoportantes [conformité]

deux types d'implémentations sont définis: hébergées et autonomes (1.4). Pour une hébergé mise en œuvre, cette norme internationale décrit l'ensemble des en-têtes disponibles.

une implémentation autonome a un ensemble d'en-têtes défini par implémentation. Cet ensemble comprend au moins les en-têtes figurant au Tableau 16.

la version fournie de l'en-tête <cstdlib> doit déclarer au moins les fonctions abort , atexit , at_quick_exit , exit , et quick_exit (18.5). Les autres en-têtes liste figurant dans ce tableau doit répondre aux mêmes exigences que pour une mise en œuvre hébergée.

Tableau 16 - C++ - têtes pour les implémentations autonomes

Subclause                           Header(s)
                                    <ciso646>
18.2  Types                         <cstddef>
18.3  Implementation properties     <cfloat> <limits> <climits>
18.4  Integer types                 <cstdint>
18.5  Start and termination         <cstdlib>
18.6  Dynamic memory management     <new>
18.7  Type identification           <typeinfo>
18.8  Exception handling            <exception>
18.9  Initializer lists             <initializer_list>
18.10 Other runtime support         <cstdalign> <cstdarg> <cstdbool>
20.9  Type traits                   <type_traits>
29    Atomics                       <atomic>

et si on utilisait int main() en C?

la norme § 5.1.2.2.1 de la norme C11 montre la notation préférée - int main(void) - mais il y a aussi deux exemples dans la norme qui montrent int main() : Paragraphe 6.5.3.4, numéro 8 §6.7.6.3 ¶20 . Maintenant, il est important de noter que les exemples ne sont pas "normatifs"; ils ne sont qu'indicatifs. Si il y a des bugs dans les exemples, ils n'affectent pas directement le texte principal de la norme. Cela dit, elles sont fortement indicatives du comportement attendu, donc si la norme inclut int main() dans un exemple, elle suggère que int main() n'est pas interdit, même si ce n'est pas la notation préférée.

6.5.3.4 les sizeof et _Alignof opérateurs

...

¶8 Exemple 3 dans cet exemple, la taille d'un tableau de longueur variable est calculée et retournée à partir d'une fonction:

#include <stddef.h>

size_t fsize3(int n)
{
    char b[n+3]; // variable length array
    return sizeof b; // execution time sizeof
}
int main()
{
    size_t size;
    size = fsize3(10); // fsize3 returns 13
    return 0;
}
102
répondu Jonathan Leffler 2017-10-05 00:43:05

je crois que main() devrait retourner soit EXIT_SUCCESS ou EXIT_FAILURE . Ils sont définis dans stdlib.h

57
répondu dmityugov 2012-09-28 03:31:37

notez que les standards C et C++ définissent deux types d'implémentations: freestanding et hosted.

  • C90 environnement hébergé

    formulaires autorisés 1 :

    int main (void)
    int main (int argc, char *argv[])
    
    main (void)
    main (int argc, char *argv[])
    /*... etc, similar forms with implicit int */
    

    commentaires:

    les deux premières sont explicitement indiquées comme les formes autorisées, les autres sont implicitement autorisées parce que C90 autorisé "int implicite" pour le type de retour et les paramètres de fonction. Aucune autre forme est autorisée.

  • C90 autonome de l'environnement

    toute forme ou nom de main est autorisé 2 .

  • C99 environnement hébergé

    formulaires autorisés 3 :

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    

    commentaires:

    C99 supprimé "implicite int" donc main() n'est plus valable.

    Une étrange, ambigu phrase "ou, dans certains autres de la mise en œuvre définies de manière" a été introduit. Ceci peut être interprété comme "les paramètres à int main() peuvent varier" ou comme "main peut avoir n'importe quelle forme définie par la mise en œuvre".

    Certains compilateurs ont choisi d'interpréter la norme dans ce dernier. On ne peut sans doute pas facilement affirmer qu'elles ne sont pas strictement conformes en citant la norme en elle-même, car elle est ambiguë.

    Cependant, pour permettre des formes complètement sauvages de main() était probablement(?) pas l'intention de cette nouvelle phrase. La logique C99 (non normative) implique que la phrase se réfère à des paramètres supplémentaires pour int main 4 .

    pourtant la section pour le programme d'environnement hébergé termination continue ensuite à argumenter sur le cas où main ne retourne pas int 5 . Bien que cette section ne soit pas normative quant à la façon dont main devrait être déclaré, elle implique certainement que main pourrait être déclaré d'une manière complètement définie par la mise en œuvre, même sur les systèmes hébergés.

  • C99 autonome de l'environnement

    toute forme ou nom de main est autorisé 6 .

  • C11 environnement hébergé

    formulaires autorisés 7 :

    int main (void)
    int main (int argc, char *argv[])
    /* or in some other implementation-defined manner. */
    
  • C11 autonome de l'environnement

    toute forme ou nom de main est autorisé 8 .


notez que int main() n'a jamais été listé comme une forme valide pour une implémentation hébergée de C dans l'une des versions ci-dessus. En C, contrairement à C++, () et (void) ont des significations différentes. Le premier est la vétusté des fonctionnalité qui peut être retiré de la langue. Voir C11 langue futures directions:

6.11.6 declarateurs de fonctions

l'utilisation de déclarateurs de fonction avec des parenthèses vides (pas prototype-format paramètre Type declarators) est une fonctionnalité obsolescente.


  • C++03 environnement hébergé

    formulaires autorisés 9 :

    int main ()
    int main (int argc, char *argv[])
    

    commentaires:

    notez la parenthèse vide dans la première forme. C++ et C sont différents dans ce cas, parce qu'en C++, cela signifie que la fonction ne prend aucun paramètre. Mais en C, cela signifie qu'il peut prendre n'importe quel paramètre.

  • C++03 autonome de l'environnement

    le nom de la fonction appelée au démarrage est implémentation-defined. Si elle est appelée main() elle doit suivre les formes indiquées 10 :

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    
  • C++11 hosted environnement

    formulaires autorisés 11 :

    int main ()
    int main (int argc, char *argv[])
    

    commentaires:

    le texte de la norme a été modifié mais il a le même sens.

  • C++11 autonome de l'environnement

    le nom de la fonction appelée au démarrage est implémentation-defined. Si elle est appelée main() il doit suivre les formulaires indiqués 12 :

    // implementation-defined name, or 
    int main ()
    int main (int argc, char *argv[])
    

références

  1. ANSI X3.159-1989 2.1.2.2 environnement hébergé. "Démarrage du programme "

    La fonction appelée au démarrage du programme est nommé principal. Le la mise en œuvre ne prévoit aucun prototype pour cette fonction. Il est être défini avec un type de retour de int et sans paramètres:

    int main(void) { /* ... */ } 
    

    ou avec deux paramètres (appelés ici argc et argv, bien que tous les noms peuvent être utilisés, car ils sont locales à la fonction dans laquelle ils sont déclarés):

    int main(int argc, char *argv[]) { /* ... */ }
    
  2. ANSI X3.159-1989 2.1.2.1 environnement autonome:

    dans un environnement autonome (dans lequel L'exécution du programme peut prendre place, sans bénéficier d'un système d'exploitation), le nom et le type de la fonction appelée au démarrage du programme sont implémentation-défini.

  3. ISO 9899:1999 5.1.2.2 environnement hébergé - > 5.1.2.2.1 démarrage du programme

    La fonction appelée au démarrage du programme est nommé principal. Le la mise en œuvre ne déclare aucun prototype pour de cette fonction. Il doit être défini avec un type de retour de int et sans paramètres:

    int main(void) { /* ... */ } 
    

    ou avec deux paramètres (appelés ici argc et argv, bien que tous les noms peuvent être utilisés, car ils sont locales à la fonction dans laquelle ils sont déclarés):

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

    ou l'équivalent; 9)ou dans une autre application-défini manière.

  4. Justification de la Norme Internationale - Langages de Programmation - C, Révision 5.10. 5.1.2.2 environnement hébergé -- > 5.1.2.2.1 démarrage du programme

    Le comportement des arguments à la main, et de l'interaction de sortie, une principale et une atexit (voir §7.20.4.2) a été codifiée pour limiter certaines variétés indésirables dans la représentation de l'argv les chaînes, et dans le sens des valeurs renvoyées par la main.

    la spécification de argc et argv comme arguments à main reconnaît une pratique antérieure extensive. argv[argc] doit être un pointeur nul pour fournir une vérification redondante pour la fin de la liste, également sur la base de la pratique courante.

    main est la seule fonction qui peut être déclarée avec zéro ou deux arguments. (Le nombre d'arguments des autres fonctions doit correspondre exactement entre invocation et définition.) Ce cas spécial, tout simplement reconnaît la pratique répandue de laisser les arguments à main lorsque le programme n'accède pas aux chaînes d'arguments du programme. Alors que de nombreuses implémentations supportent plus de deux arguments à main, une telle pratique n'est ni bénie ni interdite par la norme; un programme qui définit main avec trois arguments n'est pas strictement conforme (voir §J. 5.1.).

  5. ISO 9899:1999 5.1.2.2 environnement hébergé -- > 5.1.2.2.3 programme résiliation

    si le type de retour de la fonction principale est un type compatible avec int, un retour de l'appel initial à la fonction principale est équivalent à appeler la fonction de sortie avec la valeur retournée par la fonction principale comme argument;11) atteindre le } qui termine la fonction principale retourne une valeur de 0. Si le type de retour n'est pas compatible avec int, l'état de terminaison retourné à l'environnement hôte n'est pas spécifié.

  6. ISO 9899:1999 5.1.2.1 environnement autostable

    dans un environnement autonome (dans lequel L'exécution du programme C peut avoir lieu sans aucun avantage d'un système d'exploitation), le nom et le type de la fonction appelée au démarrage du programme sont définis par la mise en œuvre.

  7. ISO 9899:2011 5.1.2.2 environnement hébergé - > 5.1.2.2.1 démarrage du programme

    la présente section est identique à la section C99 susmentionnée.

  8. ISO 9899:1999 5.1.2.1 environnement autostable

    la présente section est identique à la section C99 susmentionnée.

  9. ISO 14882: 2003 3.6.1 fonction principale

    une implémentation ne doit pas prédéfini r la fonction principale. Ce la fonction ne doit pas être surchargé. Il doit avoir un type de retour de type int, mais sinon son type est implémentation-défini. Toutes les implémentations doivent permettre les deux définitions suivantes de main:

    int main() { /* ... */ }
    

    et

    int main(int argc, char* argv[]) { /* ... */ }
    
  10. ISO 14882: 2003 3.6.1 fonction principale

    il est mis en œuvre-défini si une programme dans un environnement autonome est nécessaire pour définir une fonction principale.

  11. ISO 14882: 2011 3.6.1 fonction principale

    une implémentation ne doit pas prédéfini r la fonction principale. Cette fonction ne doit pas être surchargé. Il doit avoir un type de retour de type int, mais sinon son type est implémentation-défini. Toutes les implémentations doivent autoriser les deux

    - un fonction de () retour int et

    - une fonction de (int, pointeur à pointeur à char) retour int

    comme type de main (8.3.5).

  12. ISO 14882: 2011 3.6.1 fonction principale

    cette section est identique à la C++03 citée ci-dessus.

29
répondu Lundin 2018-02-21 07:08:17

Return 0 en cas de succès et non nulle pour l'erreur. C'est la norme utilisée par UNIX et DOS scripting pour découvrir ce qui s'est passé avec votre programme.

27
répondu Lou Franco 2008-10-15 12:16:51

gardez à l'esprit que,même si vous retournez un int, certains OS (Windows) tronquent la valeur retournée à un seul octet (0-255).

7
répondu Ferruccio 2008-10-15 15:22:13

main() en C89 et K&R C non précisé types de retour par défaut sur "int".

return 1? return 0?
  1. si vous n'écrivez pas de déclaration dans int main() , la fermeture { retournera 0 par défaut.

  2. return 0 ou return 1 sera reçu par le processus parent. Dans un shell il va dans une variable shell, et si vous exécutez votre programme former un shell et non en utilisant cette variable alors vous n'avez pas à vous soucier de la valeur de retour de main() .

Voir Comment puis-je obtenir ce que ma fonction principale est de retour? .

$ ./a.out
$ echo $?

de Cette façon, vous pouvez voir que c'est la variable $? qui reçoit l'octet le moins significatif de la valeur de retour de main() .

Dans Unix et DOS de script, return 0 sur la réussite et l' non-zéro pour l'erreur sont généralement retournés. C'est le standard utilisé par Unix et DOS scripting pour découvrir ce qui s'est passé avec votre programme et contrôler l'ensemble du flux.

7
répondu Jeegar Patel 2018-02-21 00:14:24

la valeur de retour peut être utilisée par le système d'exploitation pour vérifier comment le programme a été fermé.

valeur de retour 0 signifie généralement OK dans la plupart des systèmes d'exploitation (ceux auxquels je pense de toute façon).

il peut également être vérifié lorsque vous appelez un processus vous-même, et de voir si le programme a quitté et terminé correctement.

Il est PAS juste une programmation à la convention.

4
répondu Yochai Timmer 2016-03-13 15:14:22

La valeur de retour de main() montre comment le programme est sorti. Si la valeur de retour est zero cela signifie que l'exécution a été réussie alors que toute valeur non nulle représentera que quelque chose s'est mal passé dans l'exécution.

3
répondu Fahad Uddin 2016-03-13 15:14:52

j'avais l'impression que standard spécifie que main n'a pas besoin d'une valeur de retour car un retour réussi était basé sur OS (zéro dans l'un pouvait être un succès ou un échec dans l'autre), donc l'absence de retour était une indication pour le compilateur d'insérer le retour réussi lui-même.

Cependant j'ai l'habitude de retourner la valeur 0.

2
répondu graham.reeds 2008-10-15 12:42:47

Returning 0 devrait dire au programmeur que le programme a terminé avec succès le travail.

2
répondu Vamsi Pavan Mahesh 2016-03-13 15:18:42

ce qu'il faut retourner dépend de ce que vous voulez faire avec l'exécutable. Par exemple, si vous utilisez votre programme avec un shell en ligne de commande, vous devez retourner 0 pour un succès et un non zéro pour un échec. Alors vous seriez en mesure d'utiliser le programme dans les coquilles avec un traitement conditionnel selon le résultat de votre code. Aussi, vous pouvez assigner n'importe quelle valeur non nulle selon votre interprétation, par exemple pour les erreurs critiques différents points de sortie de programme pourraient terminer un programme avec différentes valeurs de sortie , et qui est disponible pour le shell appelant qui peut décider quoi faire en inspectant la valeur retournée. Si le code n'est pas destiné à être utilisé avec des shells et que la valeur retournée ne dérange personne, alors il peut être omis. J'utilise personnellement la signature int main (void) { .. return 0; .. }

1
répondu phoxis 2012-09-28 03:32:13

si vous avez vraiment des problèmes liés à l'efficacité de retourner un entier d'un processus, vous devriez probablement éviter d'appeler ce processus tellement de fois que cette valeur de retour devient un problème.

si vous faites cela (appelez un processus tellement de fois), vous devriez trouver un moyen de mettre votre logique directement à l'intérieur de l'appelant, ou dans un fichier DLL, sans affecter un processus spécifique pour chaque appel; les allocations de processus multiples vous apportent le problème d'efficacité pertinent dans ce cas.

en détail, si vous voulez seulement savoir si retourner 0 est plus ou moins efficace que retourner 1, cela pourrait dépendre du compilateur dans certains cas, mais de façon générique, en supposant qu'ils sont lus à partir de la même source (locale, de champ, constante, intégrée dans le code, résultat de la fonction, etc.) il exige exactement le même nombre de cycles d'horloge.

1
répondu Luca C. 2016-03-13 15:12:55

Quelle est la façon correcte (la plus efficace) de définir la fonction main() en C et C++ - int main() ou void main() - et pourquoi?

ces mots "(le plus efficace) " ne changent pas la question. Sauf si vous êtes dans un environnement autonome, il y a une façon universellement correcte de déclarer main() , et c'est comme retourner int.

Quoi main() de retour dans le C et le C++?

ce n'est pas ce que devrait main() retour, c'est ce que fait main() retour. main() est, bien sûr, une fonction que quelqu'un appelle. Vous n'avez aucun contrôle sur le code qui appelle main() . Par conséquent, vous devez déclarer main() avec une signature type correcte pour correspondre à son appelant. Simplement, vous n'avez pas le choix en la matière. Vous n'avez pas à vous demander ce qui est plus ou moins efficace, ou ce qui est mieux ou pire style, ou quelque chose comme ça, parce que la réponse est déjà parfaitement bien définie, pour vous, par les normes C et c+. Il suffit de suivre.

Si int main() alors retourne 1 ou 0?

0 pour le succès, non zéro pour l'échec. Encore une fois, pas quelque chose que vous devez (ou) de sélection: il est défini par l'interface, vous êtes censé être conforme.

1
répondu Steve Summit 2017-10-03 21:56:28

en C++ la fonction principale doit être déclarée comme int main() et non pas void main() car le compilateur lance alors une erreur dans le cas de void main. La fonction principale peut prendre n'importe quel nombre d'arguments comme int main(int k,int l,int arr[]) ou int main(void).

#include <iostream>
using namespace std;

int main(void) {
    // your code goes here
    cout<<"a";
    return 0;
}

sortie:

Success #stdin #stdout 0s 4416KB
a

en venant à la partie de retour, il ne doit retourner que 0 sinon le compilateur envoie une erreur. par exemple, si vous revenez 1,vous obtenez le résultat souhaité mais il jette aussi une erreur d'exécution.

exemple

#include <iostream>
using namespace std;

int main(int k,float m,char g, int arr[]) {
    // your code goes here
    k=0;
    cout<<k;
    g='a';
    cout<<g;
    cout<<"a";
    return 1;
}

sortie:

Runtime error   #stdin #stdout 0s 4448KB
0aa
1
répondu Somit 2018-02-23 05:26:23

Voici une petite démonstration de l'utilisation de codes de retour...

Lorsqu'on utilise les différents outils que le terminal Linux fournit, on peut utiliser le code de retour par exemple pour le traitement des erreurs après que le processus a été terminé. Imaginez que le fichier de texte suivant myfile est présent:

ceci est un exemple pour vérifier comment fonctionne grep.

lorsque vous exécutez la commande grep a processus est créé. Une fois qu'il est passé (et ne s'est pas cassé) il renvoie un code entre 0 et 255. Par exemple:

$ grep order myfile

Si vous n'

$ echo $?
$ 0

vous obtiendrez un 0. Pourquoi? Parce que grep a trouvé une correspondance et retourné un code de sortie 0, qui est la valeur habituelle pour quitter avec un succès. Vérifions à nouveau mais avec quelque chose qui n'est pas dans notre fichier texte et donc aucune correspondance ne sera trouvée:

$ grep foo myfile
$ echo $?
$ 1

Depuis grep pas correspondre aux jeton "foo" avec le contenu de notre fichier le code de retour est 1 (c'est le cas d'habitude lorsqu'une défaillance se produit, mais comme indiqué ci-dessus, vous avez beaucoup de valeurs à choisir).

maintenant le script bash suivant (simplement le taper dans un terminal Linux) bien que très basique devrait donner une idée de la gestion des erreurs:

$ grep foo myfile
$ CHECK=$?
$ [ $CHECK -eq 0] && echo 'Match found'
$ [ $CHECK -ne 0] && echo 'No match was found'
$ No match was found

après la deuxième ligne rien n'est imprimé au terminal depuis " foo" fait grep return 1 et nous vérifions si le code de retour de grep était égal à 0. Le second énoncé conditionnel fait écho à son message dans la dernière ligne puisqu'il est vrai en raison de CHECK == 1.

comme vous pouvez voir si vous appelez ceci et ce processus, il est parfois essentiel de voir ce qu'il a retourné (par la valeur de retour de main()).

0
répondu rbaleksandar 2016-03-13 15:36:48

Omettre return 0

Lorsqu'un programme C ou c++ atteint la fin de main , le compilateur générera automatiquement du code pour retourner 0, Il n'est donc pas nécessaire de mettre return 0; explicitement à la fin de main .

Note: quand je fais cette suggestion, elle est presque invariablement suivie d'une de deux sortes de commentaires: "Je ne savais pas cela."ou "C'est un mauvais conseil!"Ma raison d'être est que c'est sûr et utile pour se fier au comportement du compilateur explicitement pris en charge par la norme. Pour C, depuis C99; voir ISO / IEC 9899: 1999 section 5.1.2.2.3:

[...] un retour de l'appel initial à la fonction main équivaut à appeler la fonction exit avec la valeur renvoyée par la fonction main comme argument; atteindre la fonction } qui termine la fonction main renvoie une valeur de 0.

pour C++, depuis la première norme en 1998; voir ISO / IEC 14882: 1998 section 3.6.1:

si le contrôle atteint la fin de main sans rencontrer de déclaration de retour, l'effet est celui d'exécuter le retour 0;

toutes les versions des deux standards depuis lors (C99 et C++98) ont maintenu la même idée. Nous nous appuyons sur les fonctions de membre générées automatiquement en C++, et peu de gens écrivent explicitement return; déclarations à la fin d'une fonction void . Les raisons contre l'omission semblent se résumer à "il semble bizarre " . Si, comme moi, vous êtes curieux de connaître la raison d'être de la modification de la norme C , lisez la question . Il convient également de noter qu'au début des années 1990, cette pratique était considérée comme "négligente" parce qu'elle n'était pas définie (bien que largement appuyée) à l'époque.

donc je recommande de l'omettre; d'autres sont en désaccord (souvent avec véhémence!) Dans tous les cas, si vous rencontrez du code qui l'omet, vous saurez qu'il est explicitement pris en charge par la norme et vous saurez ce qu'il signifie.

0
répondu Edward 2017-05-23 12:02:46