Encerramento de programa no C++

No C++, você pode sair de um programa dessas maneiras:

  • Chame a função exit.
  • Chame a função abort.
  • Execute uma return instrução de main.

Função exit

A função exit, declarada em <stdlib.h>, encerra um programa em C++. O valor fornecido como argumento para exit é retornado para o sistema operacional como o código de retorno ou o código de saída do programa. Por convenção, um código de retorno de zero indica que o programa foi encerrado com êxito. Você pode usar as constantes EXIT_FAILURE e EXIT_SUCCESS, definidas em <stdlib.h>, para indicar o êxito ou a falha do programa.

Função abort

A função abort, também declarada no arquivo de inclusão padrão <stdlib.h>, encerra um programa C++. A diferença entre exit e abort é que exit permite que o processamento de encerramento do tempo de execução C++ ocorra (os destruidores de objeto globais serão chamados). abort encerrará o programa imediatamente. A função abort ignora o processo normal de destruição para objetos estáticos globais inicializados. Também ignora o processamento especial que foi especificado usando a função atexit.

Específico da Microsoft: por motivos de compatibilidade do Windows, a implementação da Microsoft de abort pode permitir que o código de encerramento de DLL seja executado em determinadas circunstâncias. Para obter mais informações, consulte abort.

Função atexit

Use a função atexit para especificar ações que são executadas antes do término do programa. Nenhum objeto estático global inicializado antes da chamada para atexit é destruído antes da execução da função de processamento por saída.

return instrução em main

A instrução return permite retornar um valor com base em main. Uma instrução return em main primeiro lugar age como qualquer outra instrução return. Todas as variáveis automáticas são destruídas. Em seguida, main invoca exit com o valor retornado como um parâmetro. Considere o seguinte exemplo:

// return_statement.cpp
#include <stdlib.h>
struct S 
{
    int value;
};
int main()
{
    S s{ 3 };

    exit( 3 );
    // or
    return 3;
}

As instruções exit e return no exemplo anterior têm um comportamento semelhante. Ambos encerram o programa e retornam um valor de 3 para o sistema operacional. A diferença é que exit isso não destrói a variável sautomática, enquanto a instrução return o faz.

Normalmente, o C++ requer que as funções que têm tipos de retorno diferentes de void retornem um valor. A função main é uma exceção; ela pode terminar sem uma instrução return. Nesse caso, ele retorna um valor específico da implementação para o processo de invocação. (Por padrão, MSVC retorna 0.)

Destruição de threads e objetos estáticos

Quando você chama exit diretamente (ou quando é chamado após uma instrução return de main) objetos thread associados ao thread atual são destruídos. Em seguida, os objetos estáticos são destruídos na ordem inversa de sua inicialização (após chamadas para funções especificadas para atexit, se houver). O exemplo a seguir mostra como realizar essa inicialização e as tarefas de limpeza.

Exemplo

No exemplo a seguir, os objetos estáticos sd1 e sd2 são criados e inicializados antes da entrada em main. Depois que esse programa terminar de usar a instrução return, sd2 será destruído primeiro, e depois sd1. O destruidor da classe ShowData fecha os arquivos associados a esses objetos estáticos.

// using_exit_or_return1.cpp
#include <stdio.h>
class ShowData {
public:
   // Constructor opens a file.
   ShowData( const char *szDev ) {
   errno_t err;
      err = fopen_s(&OutputDev, szDev, "w" );
   }

   // Destructor closes the file.
   ~ShowData() { fclose( OutputDev ); }

   // Disp function shows a string on the output device.
   void Disp( char *szData ) {
      fputs( szData, OutputDev );
   }
private:
   FILE *OutputDev;
};

//  Define a static object of type ShowData. The output device
//   selected is "CON" -- the standard output device.
ShowData sd1 = "CON";

//  Define another static object of type ShowData. The output
//   is directed to a file called "HELLO.DAT"
ShowData sd2 = "hello.dat";

int main() {
   sd1.Disp( "hello to default device\n" );
   sd2.Disp( "hello to file hello.dat\n" );
}

Outra maneira de escrever o código é declarar os objetos ShowData com escopo de bloco, o que os destrói implicitamente quando eles saem do escopo:

int main() {
   ShowData sd1( "CON" ), sd2( "hello.dat" );

   sd1.Disp( "hello to default device\n" );
   sd2.Disp( "hello to file hello.dat\n" );
}

Confira também

função main e argumentos de linha de comando