¿De dónde vino la "salida (-1)"?

22

Veo en una gran cantidad de software heredado y malos tutoriales en Internet que recomiendan usar exit(-1), return -1o similar, para representar la "terminación anormal". El problema es que, al menos en POSIX, -1nunca ha sido y no es un código de estado válido. man 3 exitilustra que exit()devuelve el valor de status & 0377al padre, lo que significa que se -1convierte en 255. En sistemas que no son POSIX, EXIT_FAILUREse recomienda para la portabilidad. Pero nunca veo "-1 significa terminación anormal" junto con "EXIT_FAILURE puede ser algo distinto de 1", lo que indica que creen claramente que "-1" es convencional incluso en sistemas que no son POSIX.

Aquí hay un ejemplo de una pregunta de StackOverflow que perpetúa esto. El software "no realircd" también es un ejemplo de un programa que se utiliza exit(-1)para finalizar el programa. En la práctica, esto dificulta la interacción con ellos systemd.

¿De dónde vino este antipatrón? ¿Es válido en algún contexto?

usuario222973
fuente
1
"Los sistemas tipo Unix tienen una convención fuerte de que un estado de salida de 0 denota éxito, y cualquier estado de salida que no sea cero denota falla ... Esta convención está bastante conectada a los shells de Unix ..." ( Estado de salida que no es cero para salida limpia )
mosquito el
@gnat Según el manual de libc, el estado de salida es explícitamente de 0 a 255 inclusive. Si hay una respuesta en alguna parte que indique que los valores negativos fueron válidos en un punto, lo aceptaría, pero me parece muy dudoso.
user222973
1
@gnat "255" cabe fácilmente en un unsigned char.
user222973
1
@gnat Un byte en "Java" no es un carácter sin signo, es más equivalente a un charya que su rango de valores es -128 a 127. Además, ya dije "-1" se convierte en "255" en mi cuerpo de preguntas .
user222973

Respuestas:

20

Casi todas las computadoras Unix usan dos-complemento para enteros, y en dos-complemento -1 siempre es "todos los bits 1" independientemente del tamaño de la palabra. Si desea el código de salida más grande posible, independientemente del tamaño del estado de salida del programa, usar -1 y dejar que la biblioteca se trunca convenientemente hace el truco.

Eso es útil porque cuando los scripts o programas tienen más de un estado de salida posible (ver grepun ejemplo simple), los más significativos generalmente se asignan a los números más pequeños, lo que hace que el código de salida más grande sea bueno para "error desconocido" o " abortar ", ya que es poco probable que entre en conflicto con un valor de estado significativo.

Todd Knarr
fuente
Tome glibc como ejemplo, que implementa exit()como status &= 0xff. ¿Hay un "tamaño de palabra" en el que -1 & 0xffno sea 255? Por supuesto que no, porque todo el propósito es hacerlo encajar en el rango de 0-255. De todos modos, su última oración no tiene sentido: los códigos de estado 128-255 tienen un propósito especial en los sistemas UNIX.
user222973
2
No confunda los valores de salida de Bash (que son 0-127, 128+ son valores de Bash especiales) con los valores de salida del programa (que son 0-255, consulte pubs.opengroup.org/onlinepubs/009695399/functions/exit.html ). En cuanto al tamaño, recuerde que los programadores de C han estado lidiando con múltiples tamaños de palabras (originalmente 12, 16 y 32 bits) desde el principio, por lo que automáticamente buscamos modismos que no requieren que consideremos el tamaño de las palabras. Dado que Unix es anterior a Posix por 2 décadas, no siempre hubo una limitación de 8 bits, por lo que escribimos, por lo que no importó.
Todd Knarr