De onde veio "exit (-1)"?

22

Eu vejo em um monte de software legado e maus tutoriais na Internet que recomendo o uso exit(-1), return -1ou similar para representar "finalização anormal". O problema é que, pelo menos no POSIX, -1nunca foi e não é um código de status válido. man 3 exitilustra que exit()retorna o valor de status & 0377para o pai, o que significa que ele -1se torna 255. Em sistemas não POSIX, EXIT_FAILUREé recomendado para portabilidade. Mas nunca vejo "-1 significa rescisão anormal" em conjunto com "EXIT_FAILURE pode ser algo diferente de 1", indicando que eles acreditam claramente que "-1" é convencional, mesmo em sistemas não POSIX.

Aqui está um exemplo de uma pergunta StackOverflow que perpetua isso. O software "unrealircd" também é um exemplo de programa usado exit(-1)para finalizar o programa. Na prática, isso dificulta a interface systemd.

De onde veio esse anti-padrão? É válido em algum contexto?

user222973
fonte
1
"Os sistemas do tipo Unix têm uma convenção forte de que um status de saída 0 indica sucesso e qualquer status de saída diferente de zero indica falha ... Essa convenção é praticamente conectada aos shells do Unix ..." ( Status de saída diferente de zero para saída limpa )
gnat
@gnat De acordo com o manual libc, o status de saída é explicitamente de 0 a 255, inclusive. Se há uma resposta em algum lugar que afirma que os valores negativos eram válidos em um ponto, eu aceitaria isso, mas acho isso altamente duvidoso.
precisa saber é o seguinte
1
@gnat "255" cabe facilmente em um unsigned char.
precisa saber é o seguinte
1
@gnat Um byte em "Java" não é um caractere não assinado, é mais equivalente a um, charpois seu intervalo de valores é -128 a 127. Além disso, eu já afirmei que "-1" é convertido em "255" no corpo da minha pergunta .
precisa saber é o seguinte

Respostas:

20

Quase todos os computadores Unix usam complemento duplo para números inteiros, e no complemento duplo -1 é sempre "todos os bits 1", independentemente do tamanho da palavra. Se você deseja o maior código de saída possível, independentemente do tamanho do status de saída do programa, use -1 e deixe a biblioteca truncá-lo convenientemente.

Isso é útil porque, quando scripts ou programas têm mais de um status de saída possível (veja grepum exemplo simples), os significativos são geralmente atribuídos aos menores números, tornando o maior código de saída possível um bom para "erro desconhecido" ou " abortar ", pois é improvável que entre em conflito com um valor de status significativo.

Todd Knarr
fonte
Tome glibc como um exemplo, que implementa exit()como status &= 0xff. Existe um "tamanho de palavra" no qual -1 & 0xffnão é 255? Claro que não, porque o objetivo é ajustá-lo no intervalo de 0 a 255. Independentemente disso, sua última frase não faz sentido: os códigos de status 128-255 têm um propósito especial nos sistemas UNIX.
precisa saber é o seguinte
2
Não confunda valores de saída do Bash (que são 0-127, sendo 128+ valores especiais do Bash) com valores de saída do programa (que são 0-255, consulte pubs.opengroup.org/onlinepubs/009695399/functions/exit.html ). Quanto ao tamanho, lembre-se de que os programadores C lidam com vários tamanhos de palavras (originalmente 12, 16 e 32 bits) desde o início, portanto tentamos automaticamente idiomas que não exijam que consideremos o tamanho das palavras. Como o Unix antecede o Posix há duas décadas, nem sempre havia a limitação de 8 bits, então escrevemos para que não importasse.
Todd Knarr