D'où vient la «sortie (-1)»?

22

Je vois dans beaucoup de logiciels hérités et de mauvais tutoriels sur Internet qui recommandent d'utiliser exit(-1), return -1ou similaire, pour représenter une «terminaison anormale». Le problème est, dans POSIX au moins, -1n'a jamais été et n'est pas un code d'état valide. man 3 exitillustre qui exit()renvoie la valeur de status & 0377au parent, ce qui signifie que -1devient 255. Sur les systèmes non POSIX, EXIT_FAILUREest recommandé pour la portabilité. Mais je ne vois jamais "-1 signifie une terminaison anormale" en conjonction avec "EXIT_FAILURE peut être autre chose que 1", indiquant qu'ils croient clairement que "-1" est conventionnel même sur les systèmes non-POSIX.

Voici un exemple d'une question StackOverflow qui perpétue cela. Le logiciel "unrealircd" est également un exemple de programme utilisé exit(-1)pour terminer le programme. En pratique, cela rend difficile l'interface avec systemd.

D'où vient cet anti-modèle? Est-il valable dans un certain contexte?

user222973
la source
1
"Les systèmes de type Unix ont une convention forte selon laquelle un état de sortie de 0 indique le succès, et tout état de sortie non nul indique un échec ... Cette convention est à peu près câblée dans les shells Unix ..." (État de sortie non nul pour une sortie propre )
moucher le
@gnat Selon le manuel libc, l'état de sortie est explicitement compris entre 0 et 255 inclus. S'il y a une réponse quelque part qui déclare que les valeurs négatives étaient valides à un moment donné, je l'accepterais, mais je trouve cela très douteux.
user222973
1
@gnat "255" s'intègre facilement dans un unsigned char.
user222973
1
@gnat Un octet dans "Java" n'est pas un caractère non signé, il est plus équivalent à un charpuisque sa plage de valeurs est de -128 à 127. De plus, j'ai déjà déclaré que "-1" était converti en "255" dans le corps de ma question .
user222973

Réponses:

20

Presque tous les ordinateurs Unix utilisent un complément à deux pour les entiers, et dans le complément à deux -1 est toujours "tous les bits 1" quelle que soit la taille du mot. Si vous voulez le code de sortie le plus grand possible quelle que soit la taille de l'état de sortie du programme, utiliser -1 et laisser la bibliothèque le tronquer commodément fait l'affaire.

C'est utile parce que lorsque les scripts ou les programmes ont plus d'un état de sortie possible (voir grepun exemple simple), les plus significatifs sont généralement affectés aux plus petits nombres, ce qui rend le plus grand code de sortie possible un bon à utiliser pour "erreur inconnue" ou " abandonner ", car il est peu probable qu'il entre en conflit avec une valeur de statut significative.

Todd Knarr
la source
Prenez la glibc comme exemple, qui implémente exit()comme status &= 0xff. Y a-t-il une "taille de mot" qui -1 & 0xffn'est pas 255? Bien sûr que non, car tout le but est de l'adapter à une plage de 0 à 255. Quoi qu'il en soit, votre dernière phrase n'a pas de sens: les codes d'état 128-255 ont une fonction spéciale dans les systèmes UNIX.
user222973
2
Ne confondez pas les valeurs de sortie Bash (qui sont 0-127, 128+ étant des valeurs Bash spéciales) avec des valeurs de sortie de programme (qui sont 0-255, voir pubs.opengroup.org/onlinepubs/009695399/functions/exit.html ). En ce qui concerne la taille, rappelez-vous que les programmeurs C ont traité plusieurs tailles de mots (à l'origine 12, 16 et 32 ​​bits) depuis le début, nous essayons donc automatiquement des idiomes qui ne nous obligent pas à prendre en compte la taille des mots. Étant donné qu'Unix est antérieur à Posix de 2 décennies, il n'y avait pas toujours de limitation à 8 bits, nous avons donc écrit, donc cela n'avait pas d'importance.
Todd Knarr