Finalización del programa C++

En C++, puede salir de un programa de estas maneras:

  • Llame a la función exit.
  • Llame a la función abort.
  • Ejecute una instrucción return desde main.

exitFunción

La función exit, declarada en <stdlib.h>, finaliza un programa de C++. El valor proporcionado como argumento a exit se devuelve al sistema operativo como código de retorno o código de salida del programa. Por convención, un código de retorno de cero significa que el programa se completó correctamente. Puede utilizar las constantes EXIT_FAILURE y EXIT_SUCCESS, también definidas en <stdlib.h>, para indicar si el programa se ha completado correctamente o ha generado errores.

abortFunción

La función abort, declarada también en el archivo de inclusión estándar <stdlib.h>, finaliza un programa de C++. La diferencia entre exit y abort es que exit permite que tenga lugar el procesamiento de finalización en tiempo de ejecución de C++ (se llamará a los destructores de objetos globales). abort finaliza el programa inmediatamente. La función abort omite el proceso de destrucción normal de los objetos estáticos globales inicializados. También omite cualquier procesamiento especial especificado mediante la función atexit.

Específico de Microsoft: por motivos de compatibilidad de Windows, la implementación de Microsoft de abort puede permitir que el código de terminación DLL se ejecute en determinadas circunstancias. Para obtener más información, vea abort.

atexitFunción

Use la función atexit para especificar las acciones que se ejecutan antes de que finalice el programa. Los objetos estáticos no globales inicializados antes de la llamada a atexit se destruyen antes de la ejecución de la función de procesamiento de salida.

Instrucción return en main

La instrucción return le permite especificar un valor devuelto desde main. Una instrucción return en main primero actúa como cualquier otra instrucción return. Las variables automáticas se destruyen. A continuación, main invoca exit con el valor devuelto como parámetro. Considere el ejemplo siguiente:

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

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

Las instrucciones exit y return del ejemplo anterior tienen un comportamiento similar. Ambos finalizan el programa y devuelven un valor de 3 al sistema operativo. La diferencia es que exit no destruye la variable automática s, mientras que la instrucción return sí.

Por lo general, C++ requiere que las funciones que tienen tipos de valor devuelto distintos de void devuelvan un valor. La función main es una excepción; puede terminar sin una instrucción return. En ese caso, devuelve un valor específico de la implementación al proceso de invocación. (De forma predeterminada, MSVC devuelve 0).

Destrucción de subprocesos y objetos estáticos

Cuando se llama exit directamente (o cuando se llama después de una instrucción return de main), se destruyen los objetos de subproceso asociados al subproceso actual. A continuación, los objetos estáticos se destruyen en el orden inverso de su inicialización (después de las llamadas a funciones especificadas en atexit, si existen). En el ejemplo siguiente se muestra cómo funcionan esa inicialización y limpieza.

Ejemplo

En el ejemplo siguiente, los objetos estáticos sd1 y sd2 se crean e inicializan antes de la entrada a main. Después de que finalice este programa mediante la instrucción return, primero se destruye sd2 y después sd1. El destructor para la clase de ShowData cierra los archivos asociados a estos 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" );
}

Otra forma de escribir este código es declarar los objetos ShowData con ámbito de bloque, lo que permite destruirlos cuando salen del ámbito:

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

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

Consulte también

Función main y argumentos de la línea de comandos