Plage de valeur de retour de la fonction principale

Que dit la norme sur la plage de valeurs de retour principale? Dis seulement jusqu’à 255?

Parce que

int main(void){ return 256; } echo $? ; # out 0 

La norme ne dit pas. 0 , EXIT_SUCCESS et EXIT_FAILURE ont (en quelque sorte) les significations spécifiées. Tout le rest dépend de la mise en œuvre.

À l’heure actuelle, la plupart des systèmes Unix ne prennent en charge que les valeurs de retour 8 bits. Windows prend en charge (au moins) une valeur de retour 32 bits. Je n’ai pas vérifié si Windows 64 bits prend en charge une valeur de retour 64 bits, mais j’en doute, car même Windows 64 bits utilise toujours un int 32 bits.

Comme d’autres l’ont déjà indiqué, les normes C & C ++ ne limitent pas les valeurs de retour, sauf pour indiquer que (1) main renvoie un int (dont la taille est définie par l’implémentation) et que (2) zéro (ou EXIT_SUCCESS ) est un retour réussi et EXIT_FAILURE est un retour non réussi. Il spécifie qu’une main qui ne retourne pas explicitement une valeur est traitée comme si elle avait renvoyé zéro.

Dans ce cas, l’interprétation de la valeur de retour dépend du processus qui attend son achèvement (en appelant wait , waitpid ou waitid ). wait et waitpid sont les anciennes fonctions POSIX et spécifient que seuls les huit bits les moins significatifs de la valeur de retour doivent être disponibles pour un processus parent en attente . POSIX: 2008 standard ajouté waitid en tant que méthode d’attente généralisée permettant d’accéder au statut de sortie complet d’un processus enfant.

Après la suppression d’un sous-processus, un autre processus appelle l’une des fonctions d’ attente pour qu’elle se couche jusqu’à la fin du processus (le retour de la tâche main , les appels exit ou abort etc.). Les fonctions wait et waitpid renvoient l’ état par un pointeur sur un entier. L’appelant extrait le statut de sortie réel à l’aide des WIFEXITED(status_val) et WEXITSTATUS(status_val) . Ce dernier est défini par POSIX et doit renvoyer les 8 bits de poids faible de l’argument status . La fonction waitid utilise un pointeur sur une structure siginfo_t pour renvoyer les informations d’état du processus. Le membre si_status contient la valeur de statut complet, comme décrit dans Informations sur le statut .

Fondamentalement, les valeurs du statut de sortie sont dans l’ œil du spectateur . Les spécifications ANSI / ISO sont ouvertes. La suite POSIX dispose de plusieurs façons d’attendre qu’un processus se termine et d’extraire son statut de sortie. POSIX définit également spawn comme une version plus légère d’ exec qui a son propre ensemble de contraintes sur les valeurs de statut de sortie. Les shells ont l’habitude de restreindre davantage les valeurs des résultats – bash de GNU limite l’état de retour à 7 bits et un shell compatible POSIX limite les valeurs d’état de sortie à 8 bits. FWIW, la plupart des gens s’accordent à dire que le fait de limiter les valeurs de retour inférieures à 64 semble être sûr .

Les codes de sortie sont un nombre compris entre 0 et 255 inclus sur les systèmes de type Unix. Vous pouvez retourner n’importe quoi, mais sous Linux, il est moddé 256. Jetez un coup d’oeil ici pour une bonne explication sur les codes de retour Linux. Il existe également un article de Wikipedia sur le sujet qui parle rapidement des codes de sortie pour Windows.

La norme C n’impose pas de limitation particulière aux codes de sortie, le paragraphe relatif à la valeur de retour des delegates main à la documentation relative à la fonction exit() , qui indique à son tour:

Si la valeur de status est zéro ou EXIT_SUCCESS , une forme de la terminaison avec succès définie par l’implémentation est renvoyée. Si la valeur de status est EXIT_FAILURE , une forme définie par l’implémentation de la terminaison status non réussie est renvoyée. Sinon, le statut renvoyé est défini par l’implémentation.

qui, outre les EXIT_SUCCESS / EXIT_FAILURE , signifie fondamentalement “faites ce que vous voulez”. :)

Comme indiqué dans un commentaire, le fait que, sur les systèmes POSIX, seuls les 8 bits inférieurs du code de sortie soient réellement pris en compte n’est qu’un UNIXisme, dérivant de la conception du syscall wait (le statut de sortie doit être compressé dans les 8 bits inférieurs). de la valeur de retour d’ wait ) et n’a rien à voir avec le standard C.

Un contre-exemple est Windows, où toute la valeur passée à exit / return est prise en compte (tant que ce n’est pas plus gros qu’un DWORD 1 , mais je ne pense pas qu’ils vont jamais faire en sorte que int soit plus gros qu’un DWORD , cela briserait beaucoup de code).


1. Parce que le paramètre GetExitCodeProcess réservé pour renvoyer cette valeur est un DWORD * .

Sous Unix, l’appel système d’attente définit une valeur d’état de type int emballée sous forme de champ de bits avec divers types d’informations de terminaison enfant. Si l’enfant se termine en quittant (comme déterminé par la macro WIFEXITED; l’alternative habituelle étant qu’il est décédé d’un signal non capturé), SUS spécifie que les 8 bits inférieurs de la valeur de statut contiennent l’état de sortie. cela peut être récupéré en utilisant la macro WEXITSTATUS dans wait.h. En tant que tel, sous Unix, les états de sortie sont limités aux valeurs 0 à 255 , la plage d’un entier non signé de 8 bits.

Les systèmes similaires à Unix utilisent généralement une convention de zéro pour réussir et de zéro pour les erreurs. Certaines conventions ont été développées quant à la signification relative de divers codes d’erreur; Par exemple, GNU recommande que les codes avec le bit élevé soient réservés aux erreurs graves, et FreeBSD a documenté un large éventail d’interprétations préférées.

La norme C99 définit uniquement les valeurs 0 et 1. Toutefois, elle permet d’utiliser d’autres valeurs.

Voir le wiki sur le statut de sortie pour plus d’informations.

Vous retournez le type int . Vous devriez pouvoir renvoyer n’importe quelle valeur pouvant être stockée dans un int . La taille exacte d’un int dépend de l’implémentation, je ne peux donc pas vous donner d’intervalle exact.

5.1.2.2.3 Fin du programme 1 Si le type de retour de la fonction principale est un type compatible avec int, un retour de l’appel initial vers la fonction principale équivaut à l’appel de la fonction de sortie avec la valeur renvoyée par la fonction principale. argument; 10) atteindre le} qui termine la fonction principale renvoie 0. Si le type de retour n’est pas compatible avec int, l’état de la terminaison renvoyé à l’environnement hôte est non spécifié.

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf

c’est-à-dire qu’il n’est pas nécessaire de renvoyer quoi que ce soit. Cependant, il indique clairement à partir de là quelles sont les définitions habituelles. Cela sous-entend presque qu’ils sont standard, mais que la carte est gratuite, ce qui signifie que cela peut être n’importe quoi.