Exit () faz algo especial que 'return' não faz?
Com alguns compiladores para plataformas incomuns, exit()
pode converter seu argumento no valor de saída do seu programa enquanto um retorno demain()
apenas pode passar o valor diretamente para o ambiente host sem nenhuma tradução.
O padrão requer um comportamento idêntico nesses casos (especificamente, ele diz que retornar algo que é int
compatível main()
deve ser equivalente a chamar exit()
com esse valor). O problema é que sistemas operacionais diferentes têm convenções diferentes para interpretar os valores de saída. Em muitos sistemas (MUITOS!), 0 significa sucesso e qualquer outra coisa é um fracasso. Mas, digamos, VMS, valores ímpares significam sucesso e pares significam falha. Se você retornou 0 demain()
, um usuário do VMS receberia uma mensagem desagradável sobre uma violação de acesso. Na verdade, não houve uma violação de acesso - essa era simplesmente a mensagem padrão associada ao código de falha 0.
Então o ANSI apareceu e abençoou EXIT_SUCCESS
e EXIT_FAILURE
como argumentos você poderia passar exit()
. A norma também diz que exit(0)
deve comportar-se de forma idêntica para exit(EXIT_SUCCESS)
, assim que a maioria das implementações definir EXIT_SUCCESS
a 0
.
O padrão, portanto, coloca você em um vínculo com o VMS, pois não deixa uma maneira padrão de retornar um código de falha que possua o valor 0.
O compilador VAX / VMS C da era do início dos anos 90, portanto, não interpretou o valor de retorno main()
, simplesmente retornou qualquer valor ao ambiente host. Mas se você o utilizasse exit()
, faria o que o padrão exigia: converter EXIT_SUCCESS
(ou 0
) em um código de sucesso e EXIT_FAILURE
em um código de falha genérico. Para usar EXIT_SUCCESS
, você tinha que passá-lo para exit()
, você não poderia devolvê-lo main()
. Não sei se versões mais modernas desse compilador preservaram esse comportamento.
Um programa C portátil costumava ficar assim:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello, World!\n");
exit(EXIT_SUCCESS); /* to get good return value to OS */
/*NOTREACHED*/ /* to silence lint warning */
return 0; /* to silence compiler warning */
}
Além: Se bem me lembro, a convenção VMS para valores de saída é mais diferenciada do que ímpar / par. Na verdade, ele usa algo como os três bits baixos para codificar um nível de gravidade. De um modo geral, no entanto, os níveis ímpares de gravidade indicavam sucesso ou informações diversas e os pares indicavam erros.