Namespaces
Variants

std:: exit

From cppreference.net
Utilities library
Definido en el encabezado <cstdlib>
void exit ( int exit_code ) ;
(hasta C++11)
[ [ noreturn ] ] void exit ( int exit_code ) ;
(desde C++11)

Causa la terminación normal del programa.

Se realizan varios pasos de limpieza:

1) Los objetos con duración de almacenamiento estático son destruidos y las funciones registradas llamando a std::atexit son llamadas:
a) Los objetos no locales con duración de almacenamiento estático son destruidos en orden inverso al de la finalización de su constructor.
b) Las funciones registradas con std::atexit son llamadas en orden inverso al de su registro, excepto que una función es llamada después de cualquier función previamente registrada que ya hubiera sido llamada en el momento de su registro.
c) Para cada función f registrada con std::atexit y cada objeto no local obj de duración de almacenamiento estático,
  • si f es registrada antes de la inicialización de obj , f solo será llamada después de la destrucción de obj ;
  • si f es registrada después de la inicialización de obj , f solo será llamada antes de la destrucción de obj .
d) Para cada objeto local obj con duración de almacenamiento estático, obj es destruido como si una función que llama al destructor de obj fuera registrada con std::atexit al completarse el constructor de obj .
(hasta C++11)
1) Los destructores de objetos con duración de almacenamiento thread local que están asociados con el hilo actual, los destructores de objetos con duración de almacenamiento estático, y las funciones registradas con std::atexit se ejecutan concurrentemente, manteniendo las siguientes garantías:
a) El último destructor para objetos thread-local está secuenciado-antes del primer destructor para un objeto estático.
b) Si la finalización del constructor o la inicialización dinámica para el objeto thread-local o estático A estuvo secuenciada-antes del objeto thread-local o estático B, la finalización de la destrucción de B está secuenciada-antes del inicio de la destrucción de A.
c) Si la finalización de la inicialización de un objeto estático A estuvo secuenciada-antes de la llamada a std::atexit para alguna función F, la llamada a F durante la terminación está secuenciada-antes del inicio de la destrucción de A.
d) Si la llamada a std::atexit para alguna función F estuvo secuenciada-antes de la finalización de la inicialización de un objeto estático A, el inicio de la destrucción de A está secuenciada-antes de la llamada a F durante la terminación.
e) Si una llamada a std::atexit para alguna función F1 estuvo secuenciada-antes de la llamada a std::atexit para alguna función F2, entonces la llamada a F2 durante la terminación está secuenciada-antes de la llamada a F1.
(desde C++11)
  • En lo anterior,
  • Si cualquier función registrada con atexit o cualquier destructor de un objeto estático/de hilo local lanza una excepción, std::terminate es invocado.
  • Si el compilador optó por elevar la inicialización dinámica de un objeto a la fase de inicialización estática de inicialización no local , la secuenciación de la destrucción respeta su inicialización dinámica original.
  • Si un objeto estático de ámbito de función (bloque) fue destruido y luego esa función es llamada desde el destructor de otro objeto estático y el flujo de control pasa a través de la definición de ese objeto (o si se utiliza indirectamente, mediante puntero o referencia), el comportamiento es indefinido.
  • Si un objeto estático de ámbito de función (bloque) fue inicializado durante la construcción de un subobjeto de una clase o array, solo se destruye después de que todos los subobjetos de esa clase o todos los elementos de ese array hayan sido destruidos.
2) Todos los flujos C son vaciados y cerrados.
3) Los archivos creados por std::tmpfile son eliminados.
4) El control es devuelto al entorno anfitrión. Si exit_code es 0 o EXIT_SUCCESS , se retorna un estado definido por la implementación que indica terminación exitosa. Si exit_code es EXIT_FAILURE , se retorna un estado definido por la implementación que indica terminación fallida. En otros casos se retorna un valor de estado definido por la implementación.

La pila no se desenreda: los destructores de variables con duración de almacenamiento automática no se llaman.

Contenidos

Relación con la función main

Regresar desde la función main , ya sea mediante una sentencia return o al alcanzar el final de la función, realiza la terminación normal de la función (llama a los destructores de las variables con duraciones de almacenamiento automáticas) y luego ejecuta std::exit , pasando el argumento de la sentencia return (o 0 si se utilizó el retorno implícito) como exit_code .

Parámetros

exit_code - estado de salida del programa

Valor de retorno

(ninguno)

Ejemplo

#include <cstdlib>
#include <iostream>
struct Static
{
    ~Static() 
    {
        std::cout << "Static destructor\n";
    }
};
struct Local
{
    ~Local() 
    {
        std::cout << "Local destructor\n";
    }
};
Static static_variable; // El destructor de este objeto *será* llamado
void atexit_handler()
{
    std::cout << "atexit handler\n";
}
int main()
{
    Local local_variable; // El destructor de este objeto *no* será llamado
    const int result = std::atexit(atexit_handler); // El manejador será llamado
    if (result != 0)
    {
        std::cerr << "atexit registration failed\n";
        return EXIT_FAILURE;
    }
    std::cout << "test\n";
    std::exit(EXIT_FAILURE);
    std::cout << "this line will *not* be executed\n";
}

Salida:

test
atexit handler
Static destructor

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 3 C++98 durante la limpieza, el comportamiento no estaba claro cuando (1) una función está
registrada con std::atexit o (2) un objeto local estático es inicializado
aclarado

Véase también

provoca la terminación anormal del programa (sin limpieza)
(función)
registra una función para ser llamada al invocar std::exit()
(función)
(C++11)
provoca la terminación rápida del programa sin limpieza completa
(función)
registra una función para ser llamada al invocar std::quick_exit
(función)