Finalización del programa C++
En C++, puede salir de un programa de estas maneras:
exit
Funció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.
abort
Funció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
.
atexit
Funció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
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de