Woher kommt "exit (-1)"?

22

Ich sehe in vielen älteren Programmen und schlechten Tutorials im Internet, dass die Verwendung von oder ähnlichem empfohlen wird exit(-1), return -1um eine "abnormale Beendigung" darzustellen. Das Problem ist, zumindest in POSIX, dass es -1noch nie einen gültigen Statuscode gab und gibt. man 3 exitveranschaulicht, dass exit()der Wert von status & 0377an das übergeordnete Element zurückgegeben -1wird , was bedeutet, dass wird 255. Auf Nicht-POSIX-Systemen EXIT_FAILUREwird aus Gründen der Portabilität empfohlen. Ich sehe jedoch niemals, dass "-1 bedeutet, dass eine abnormale Beendigung vorliegt" in Verbindung mit "EXIT_FAILURE kann etwas anderes als 1 sein", was darauf hinweist, dass "-1" auch auf Nicht-POSIX-Systemen eindeutig konventionell ist.

Hier ist ein Beispiel für eine StackOverflow-Frage , die dies aufrechterhält . Die Software "unrealircd" ist auch ein Beispiel für ein Programm, mit exit(-1)dem das Programm beendet wird. In der Praxis ist es schwierig, eine Schnittstelle zu erstellen systemd.

Woher kommt dieses Anti-Pattern? Ist es in irgendeinem Zusammenhang gültig?

user222973
quelle
1
"Unix-ähnliche Systeme haben die starke Konvention, dass ein Exit-Status von 0 Erfolg und ein Exit-Status ungleich Null Fehler bedeutet ... Diese Konvention ist ziemlich fest mit Unix-Shells verbunden ..." ( Exit-Status ungleich Null) für sauberen Ausgang )
Mücke
@gnat Laut libc-Handbuch liegt der Exit-Status explizit zwischen 0 und 255 (inklusive). Wenn es irgendwo eine Antwort gibt, die besagt, dass negative Werte zu einem bestimmten Zeitpunkt gültig waren, würde ich das akzeptieren, aber ich finde das höchst zweifelhaft.
user222973
1
@gnat "255" passt leicht in eine unsigned char.
user222973
1
@gnat Ein Byte in "Java" ist kein vorzeichenloses Zeichen, es entspricht eher einem, charda sein Wertebereich zwischen -128 und 127 liegt. Außerdem habe ich bereits angegeben, dass "-1" in meinem Fragekörper in "255" umgewandelt wird .
user222973

Antworten:

20

Fast alle Unix-Computer verwenden das Zweierkomplement für ganze Zahlen, und im Zweierkomplement ist -1 unabhängig von der Wortgröße immer "alle Bits 1". Wenn Sie den größtmöglichen Exit-Code unabhängig von der Größe des Exit-Status des Programms wünschen, reicht es aus, -1 zu verwenden und die Bibliothek abschneiden zu lassen.

Dies ist nützlich, da Skripte oder Programme, die mehr als einen möglichen Exit-Status haben (siehe grepein einfaches Beispiel), in der Regel den kleinsten Zahlen zugeordnet werden, sodass der größtmögliche Exit-Code für "unbekannte Fehler" oder " abbrechen ", da es unwahrscheinlich ist, dass es jemals zu einem Konflikt mit einem aussagekräftigen Statuswert kommt.

Todd Knarr
quelle
Nehmen Sie als Beispiel glibc, das exit()als implementiert status &= 0xff. Gibt es eine "Wortgröße", in der -1 & 0xffnicht 255 ist? Natürlich nicht, denn der ganze Zweck ist es, es in den Bereich von 0-255 zu passen. Ungeachtet dessen macht Ihr letzter Satz keinen Sinn: Die Statuscodes 128-255 haben in UNIX-Systemen einen besonderen Zweck.
user222973
2
Verwechseln Sie die Bash-Exit-Werte (0-127, 128+ sind spezielle Bash-Werte) nicht mit den Programm-Exit-Werten (0-255, siehe pubs.opengroup.org/onlinepubs/009695399/functions/exit.html ). Denken Sie daran, dass C-Programmierer von Anfang an mit mehreren Wortgrößen (ursprünglich 12, 16 und 32 Bit) gearbeitet haben, sodass wir automatisch nach Redewendungen suchen, bei denen die Wortgröße nicht berücksichtigt werden muss. Da Unix 2 Jahrzehnte vor Posix liegt, gab es nicht immer die 8-Bit-Beschränkung, also haben wir geschrieben, also war das egal.
Todd Knarr