C'est une question simple, mais je continue de voir des réponses contradictoires: la routine principale d'un programme C ++ doit-elle retourner 0
ou EXIT_SUCCESS
?
#include <cstdlib>
int main(){return EXIT_SUCCESS;}
ou
int main(){return 0;}
Sont-ils exactement la même chose? Ne doit EXIT_SUCCESS
être utilisé qu'avec exit()
?
Je pensais que ce EXIT_SUCCESS
serait une meilleure option parce que d'autres logiciels peuvent vouloir considérer zéro comme un échec, mais j'ai également entendu dire que si vous revenez 0
, le compilateur est capable de le changer de toute façon en une valeur différente.
c++
c
return-value
main
Trevor Hickey
la source
la source
0
etEXIT_SUCCESS
sont toutes deux interprétées comme un succès.Réponses:
EXIT_FAILURE
, que ce soit dans une instruction return dansmain
ou en tant qu'argument deexit()
, est le seul moyen portable d'indiquer l'échec d'un programme C ou C ++.exit(1)
peut effectivement signaler une terminaison réussie sur VMS, par exemple.Si vous prévoyez d'utiliser
EXIT_FAILURE
lorsque votre programme échoue, alors vous pouvez aussi bien l'utiliserEXIT_SUCCESS
lorsqu'il réussit, juste pour des raisons de symétrie.D'un autre côté, si le programme ne signale jamais l'échec, vous pouvez utiliser soit
0
ouEXIT_SUCCESS
. Les deux sont garantis par la norme pour signaler la réussite. (Il est à peine possible que celaEXIT_SUCCESS
puisse avoir une valeur autre que 0, mais c'est égal à 0 sur chaque implémentation dont j'ai jamais entendu parler.)L'utilisation
0
a l'avantage mineur dont vous n'avez pas besoin#include <stdlib.h>
en C, ou#include <cstdlib>
en C ++ (si vous utilisez unereturn
instruction plutôt que d'appelerexit()
) - mais pour un programme de toute taille significative, vous allez inclure stdlib directement ou indirectement en tous cas.D'ailleurs, en C à partir du standard 1999, et dans toutes les versions de C ++, atteindre la fin de
main()
fait dereturn 0;
toute façon un implicite , donc vous n'aurez peut-être pas besoin d'utiliser l'un0
ou l' autre ouEXIT_SUCCESS
explicitement. (Mais au moins en C, je considère qu'unreturn 0;
style explicite est meilleur.)(Quelqu'un a posé une question sur OpenVMS. Je ne l'ai pas utilisé depuis longtemps, mais si je me souviens bien, les valeurs d'état impaires indiquent généralement le succès tandis que les valeurs paires indiquent un échec. L'implémentation C correspond
0
à1
, ce quireturn 0;
indique une fin réussie. Les autres valeurs sont transmises sans modification , doncreturn 1;
indique également une fin réussie.EXIT_FAILURE
aurait une valeur paire différente de zéro.)la source
0
etEXIT_SUCCESS
ne sont pas garantis d'avoir la même valeur (je l'ai mentionné dans ma réponse), mais ils indiquent tous deux une résiliation réussie.EXIT_SUCCESS
est stylistiquement meilleur si vous utilisez égalementEXIT_FAILURE
, mais çaexit(0)
va.Ce n'est pas important. Les deux sont identiques.
Citations standard C ++:
la source
EXIT_SUCCESS == 0
. D'un autre côté, il n'y a aucune bonne raison pour que ce ne soit pas le cas.0 est, par définition, un nombre magique. EXIT_SUCCESS est presque universellement égal à 0, heureusement. Alors pourquoi ne pas simplement retourner / quitter 0?
exit (EXIT_SUCCESS); a un sens très clair.
sortie (0); d'autre part, est contre-intuitif à certains égards. Quelqu'un qui n'est pas familier avec le comportement du shell pourrait supposer que 0 == faux == mauvais, comme toute autre utilisation de 0 en C. Mais non - dans ce cas particulier, 0 == succès == bon. Pour les développeurs les plus expérimentés, cela ne posera pas de problème. Mais pourquoi trébucher le nouveau sans aucune raison?
tl; dr - s'il y a une constante définie pour votre nombre magique, il n'y a presque jamais de raison de ne pas utiliser la constante en premier lieu. C'est plus consultable, souvent plus clair, etc. et cela ne vous coûte rien.
la source
fclose()
,setvbuf()
, ...), (POSIXlisten()
,pthread_create()
,pipe()
, ...), et beaucoup, beaucoup d' autres bibliothèques (par exemple OpenGL [glGetError()
], zlib [deflate()
/inflate()
/ ...], SDL [SDL_CreateWindowAndRenderer()
/ ...], et plus).C'est une histoire sans fin qui reflète les limites (un mythe) de "l'interopérabilité et la portabilité dans tous".
Ce que le programme doit renvoyer pour indiquer «succès» doit être défini par la personne qui reçoit la valeur (le système d'exploitation ou le processus qui a appelé le programme) et non par une spécification de langage.
Mais les programmeurs aiment écrire du code de manière "portable" et par conséquent ils inventent leur propre modèle pour le concept de "système d'exploitation" définissant les valeurs symboliques à renvoyer.
Maintenant, dans un scénario plusieurs-à-plusieurs (où de nombreux langages servent à écrire des programmes sur plusieurs systèmes), la correspondance entre la convention de langage pour «succès» et celle du système d'exploitation (que personne ne peut accorder à être toujours la même) devrait être géré par l'implémentation spécifique d'une bibliothèque pour une plate-forme cible spécifique.
Mais - malheureusement - ces concepts n'étaient pas aussi clairs au moment où le langage C a été déployé (principalement pour écrire le noyau UNIX), et les Gigagrammes de livres où écrits en disant "retour 0 signifie succès", puisque c'était vrai sur le système d'exploitation à cette fois avoir un compilateur C.
Dès lors, aucune normalisation claire n'a jamais été faite sur la manière dont une telle correspondance devrait être traitée. C et C ++ ont leur propre définition des «valeurs de retour» mais personne n'accorde une traduction correcte du système d'exploitation (ou mieux: aucune documentation du compilateur n'en dit rien). 0 signifie succès si vrai pour UNIX - LINUX et - pour des raisons indépendantes - pour Windows également, et cela couvre 90% des "ordinateurs grand public" existants, qui - dans la plupart des cas - ne tiennent pas compte de la valeur de retour (nous pouvons donc discutez pendant des décennies, mais personne ne le remarquera jamais!)
Dans ce scénario, avant de prendre une décision, posez les questions suivantes: - Suis-je intéressé à communiquer quelque chose à mon interlocuteur sur mon existant? (Si je retourne toujours 0 ... il n'y a aucun indice derrière tout) - Mon interlocuteur a-t-il des conventions sur cette communication? (Notez qu'une seule valeur n'est pas une convention: cela ne permet aucune représentation d'information)
Si les deux réponses sont non, la bonne solution est probablement de ne pas écrire du tout l'instruction de retour principale. (Et laissez le compilateur décider, en ce qui concerne la cible).
Si aucune convention n'est en place 0 = le succès satisfait la plupart des situations (et l'utilisation de symboles peut être problématique, s'ils introduisent une convention).
Si des conventions sont en place, veillez à utiliser des constantes symboliques qui sont cohérentes avec elles (et assurez la cohérence des conventions, et non la cohérence des valeurs, entre les plates-formes).
la source
Une fois que vous commencez à écrire du code qui peut renvoyer une myriade d'états de sortie, vous commencez à
#define
tous. Dans ce cas,EXIT_SUCCESS
cela a du sens dans le contexte de ne pas être un " nombre magique ". Cela rend votre code plus lisible car tous les autres codes de sortie le serontEXIT_SOMETHING
. Si vous écrivez simplement un programme qui reviendra une fois terminé, ilreturn 0
est valide et probablement même plus propre car cela suggère qu'il n'y a pas de structure de code de retour sophistiquée.la source
Ce que vous revenez d'un programme n'est qu'une convention.
Non, je ne peux penser à aucune circonstance où "EXIT_SUCCESS" ne serait pas "0".
Personnellement, je recommanderais "0".
A MON HUMBLE AVIS...
la source
0
c'est faux, et de nombreuses fonctions retournent0
en cas d'échec / ne rien faire.Si vous utilisez EXIT_SUCCESS, votre code sera plus portable.
http://www.dreamincode.net/forums/topic/57495-return-0-vs-return-exit-success/
la source
EXIT_SUCCESS
deux indiquent une résiliation réussie.Certains compilateurs pourraient créer des problèmes avec cela - sur un compilateur Mac C ++, EXIT_SUCCESS fonctionnait bien pour moi, mais sur un complicateur Linux C ++, j'ai dû ajouter cstdlib pour qu'il sache ce qu'est EXIT_SUCCESS. À part cela, ils sont identiques.
la source
EXIT_SUCCESS
travaillé sans inclure ni<stdlib.h>
ni<cstdlib>
, un autre en-tête doit l'avoir défini, directement ou indirectement. En C ++, il est courant pour les en-têtes standard vers d'#include
autres en-têtes standard. Si cela se compile sans erreur:int main() { return EXIT_SUCCESS; }
alors votre compilateur est probablement bogué.