Pergunta

Devo usar exit() ou apenas declarações return em main()? Pessoalmente sou a favor das demonstrações return porque eu sinto que é como a leitura de qualquer outra função e o controle de fluxo quando estou lendo o código é suave (na minha opinião). E mesmo se eu quiser refatorar a função main(), tendo return parece ser uma escolha melhor do que exit().

O exit() fazer especial qualquer coisa que return não?

Foi útil?

Solução

Na verdade, há é a diferença, mas é sutil. Ele tem mais implicações para C ++, mas as diferenças são importantes.

Quando eu chamo return em main(), destruidores serão chamados para os meus objetos escopo localmente. Se eu chamar exit(), não destrutor será chamado para meus objetos de escopo localmente! Re-li isso. exit() não retorna . Isso significa que uma vez que eu lhe chamo, "não há backsies." Todos os objetos que você criou em que a função não será destruído. Muitas vezes isso não tem consequências, mas às vezes ele faz, como fechar arquivos (certamente você quer todos os seus dados liberados para o disco?).

Note que os objetos static vai ser limpo mesmo se você chamar exit(). Finalmente, note que se você usar abort(), nenhum objeto será destruído. Ou seja, há objetos globais, há objetos estáticos e nenhum objeto locais terão seus destruidores chamados.

Proceda com cuidado quando favorecendo saída em relação ao regresso.

http://groups.google.com/group/gnu. gcc.help/msg/8348c50030cfd15a

Outras dicas

Outra diferença: exit é uma biblioteca padrão função que você precisa incluir cabeçalhos e ligação com o padrão biblioteca. Para ilustrar (em C ++), este é um programa válido:

int main() { return 0; }

Mas para usar exit você precisará de um incluem:

#include <stdlib.h>
int main() { exit(EXIT_SUCCESS); }

Além disso, isso adiciona uma suposição adicional: que chamar exit de main tem os mesmos efeitos colaterais como retornar zero. Como outros apontaram, isso depende de que tipo de executável que você está construindo (ou seja, quem está chamando main). Você codificação de um aplicativo que usa o C-tempo de execução? A Maya plugin? serviço de um Windows? Um motorista? Cada caso vai exigir pesquisa para ver se exit é equivalente a return. IMHO usando exit quando você realmente média return apenas torna o código mais confuso. OTOH, se você realmente média exit, em seguida, por todos os meios usá-lo.

Há pelo menos uma razão para preferir exit: Se qualquer um dos seus manipuladores atexit referem-se a dados de armazenamento automático de duração em main, ou se você usou setvbuf ou setbuf para atribuir a um dos padrões córregos um automático-Storage- tampão duração em main, em seguida, retornar de main produz um comportamento indefinido, mas chamando exit é válido.

Outro uso potencial (geralmente reservado para programas de brinquedo, no entanto) é a saída de um programa com invocações recursivas de main.

Eu sempre uso return porque o protótipo padrão para main() diz que ele não retornar um int.

Dito isto, algumas versões das normas dar tratamento especial main e assumir que ele retorna 0 se não há nenhuma declaração return explícito. Dado o seguinte código:

int foo() {}
int main(int argc, char *argv[]) {}

G ++ só gera um aviso para foo() e ignora o retorno faltando main:

% g++ -Wall -c foo.cc
foo.cc: In function ‘int foo()’:
foo.cc:1: warning: control reaches end of non-void function

I FORTEMENTE segundo o comentário de R. sobre o uso exit (), a fim de evitar que o armazenamento automático em main() recuperado antes que o programa realmente termina. Uma declaração return X; em main() não é precisamente equivalente a uma chamada para exit(X);, desde o armazenamento dinâmico de main() desaparece quando main() retornos, mas ele não desaparece se uma chamada para exit() é feito em seu lugar.

Além disso, em C ou qualquer C-como linguagem de uma declaração return dicas fortemente para o leitor que a execução vai continuar na função de chamada, e enquanto isso continuação da execução geralmente é tecnicamente verdade se você contar a rotina de arranque C que chamou a sua função main(), não é exatamente o você média quando você quer dizer para terminar o processo.

Apesar de tudo, se você quiser terminar o seu programa a partir de qualquer outra função, exceto main() você deve Chamada exit(). Ao fazê-lo de forma consistente em main() assim faz o seu código muito mais legível, e também torna muito mais fácil para qualquer um re-fator de seu código; código ou seja copiado de main() a alguma outra função não irá se comportar mal por causa de declarações return acidentais que deve ter sido chamadas exit().

Assim, combinando todos esses pontos juntos a conclusão é que é uma mau hábito , pelo menos para C, para usar uma declaração return para terminar o programa em main().

O exit () fazer qualquer coisa especial que 'retorno' não?

Com alguns compiladores para plataformas incomuns, exit() pode traduzir seu argumento em valor de saída do seu programa, enquanto um retorno de main() só poderia passar o valor diretamente para o ambiente de acolhimento, sem qualquer tradução.

A norma exige comportamento idêntico nestes casos (especificamente, diz retornar algo que é int compatível de main() deve ser equivalente a chamar exit() com esse valor). O problema é que diferentes sistemas operacionais têm diferentes convenções para interpretar os valores de saída. Em muitos sistemas (muitas!), 0 significa sucesso e qualquer outra coisa é um fracasso. Mas, digamos, VMS, valores ímpares sucesso média e mesmo os de falha média. Se você retornou 0 de main(), um usuário VMS veria uma mensagem desagradável sobre uma violação de acesso. Não havia, na verdade, uma violação de acesso -. Que era simplesmente a mensagem padrão associado com o código de falha 0

Em seguida, ANSI veio e abençoado EXIT_SUCCESS e EXIT_FAILURE como argumentos você poderia passar para exit(). A norma também diz que exit(0) deve comportar-se de forma idêntica à exit(EXIT_SUCCESS), por isso a maioria das implementações definir EXIT_SUCCESS para 0.

A norma, portanto, coloca você em um ligamento em VMS, já que deixa nenhuma maneira padrão para retornar um falha código que passa a ter o valor 0.

O início de 1990 era compilador VAX / VMS C, portanto, não interpretar o valor de retorno de main(), ele simplesmente voltou qualquer valor ao ambiente de host. Mas se você usou exit() ele faria o que o padrão exigido: traduzir EXIT_SUCCESS (ou 0) em um código de sucesso e EXIT_FAILURE em um código de falha genérico. Para uso EXIT_SUCCESS, você estiveste para passá-lo para exit(), você não poderia devolvê-lo a partir main(). Eu não sei se as versões mais modernas do que compilador preservado esse comportamento.

Um programa C portátil usado para olhar como esta:

#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 sutil do que o par / ímpar. Ele realmente usa algo como o baixo três bits para codificar um nível de gravidade. De um modo geral, no entanto, os níveis de gravidade ímpar indicado sucesso ou informações diversas e mesmo aqueles indicados erros.

Em C retornando de main é exatamente o mesmo que chamar exit com o mesmo valor.

Secção 5.1.2.2.3 do C estados padrão :

Se o tipo de retorno da função principal é um tipo compatível com int , um retorno da chamada inicial para a função principal é equivalente a chamando a função de saída com o valor retornado pelo principal função como seu argumento ; 11) atingindo o} que termina o principal função retorna um valor de 0. Se o tipo de retorno é não é compatível com int, o status de terminação retornou ao ambiente de acolhimento não é especificado.

As regras para C ++ são um pouco diferentes, como mencionado em outras respostas.

Há realmente uma diferença entre exit(0) e return(0) em main -. Quando a sua função main é chamado várias vezes

O seguinte programa

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
  if (argc == 0)
    return(0);
  printf("%d", main(argc - 1, argv));
}

Executar como

./program 0 0 0 0

resultará na seguinte resultado:

00000

No entanto esta:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
  if (argc == 0)
    exit(0);
  printf("%d", main(argc - 1, argv));
}

Não vai imprimir qualquer coisa, independentemente dos argumentos.

Se você tem certeza que ninguém vai chamar seu main explicitamente não é tecnicamente uma grande diferença em geral, mas para manter a mais clara exit código ficaria muito melhor. Se por alguma razão quiser chamar main -. Você deve ajustá-lo às suas necessidades

Falando sobre C.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top