Namespaces
Variants

std::exit

De es.cppreference.net
 
 
Biblioteca de utilidades
Soporte del lenguaje
Soporte de tipos (tipos básicos, RTTI)
Macros de prueba de características de la biblioteca (C++20)
Utilidades del programa
Funciones variádicas
Soporte de corrutinas (C++20)
Soporte de contratos (C++26)
Comparación de tres vías
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Utilidades generales
Operadores relacionales (obsoleto en C++20)
 
 
Definido en el encabezado <cstdlib>
             void exit( int exit_code );
(hasta C++11)
[[noreturn]] void exit( int exit_code );
(desde C++11)

Provoca la terminación normal del programa.

Se realizan varios pasos de limpieza:

1) Los objetos con duración de almacenamiento estático se destruyen y se llaman las funciones registradas mediante std::atexit:
a) Los objetos no locales con duración de almacenamiento estático se destruyen en el orden inverso a la finalización de su constructor.
b) Las funciones registradas con std::atexit se llaman en el orden inverso a su registro, excepto que una función se llama 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 se registra antes de la inicialización de obj, f solo se llamará después de la destrucción de obj;
  • si f se registra después de la inicialización de obj, f solo se llamará antes de la destrucción de obj.
d) Para cada objeto local obj con duración de almacenamiento estático, obj se destruye como si se hubiera registrado una función que llama al destructor de obj con std::atexit al finalizar el constructor de obj.
(hasta C++11)
1) Los destructores de objetos con duración de almacenamiento de hilo local 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 de hilo 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 un objeto de hilo local o estático A estaba secuenciada-antes que el objeto de hilo 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 estaba 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 estaba 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á secuenciado-antes de la llamada a F durante la terminación.
e) Si una llamada a std::atexit para alguna función F1 estaba 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 alguna función registrada con atexit o cualquier destructor de un objeto estático/de hilo local lanza una excepción, se llama a std::terminate.
  • Si el compilador optó por elevar la inicialización dinámica de un objeto a la fase de inicialización estática de la inicialización no local, la secuenciación de la destrucción respeta su supuesta inicialización dinámica.
  • Si un objeto estático local a una función (de ámbito de 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 usa indirectamente, a través de un puntero o referencia), el comportamiento no está definido.
  • Si un objeto estático local a una función (de ámbito de bloque) fue inicializado durante la construcción de un subobjeto de una clase o arreglo, solo se destruye después de que todos los subobjetos de esa clase o todos los elementos de ese arreglo hayan sido destruidos.
2) Todos los flujos de C se vacían y cierran.
3) Los archivos creados por std::tmpfile se eliminan.
4) El control se devuelve al entorno anfitrión. Si exit_code es 0 o EXIT_SUCCESS, se devuelve un estado definido por la implementación que indica terminación exitosa. Si exit_code es EXIT_FAILURE, se devuelve un estado definido por la implementación que indica terminación fallida. En otros casos, se devuelve un valor de estado definido por la implementación.

La pila no se desenrolla: los destructores de variables con duración de almacenamiento automática no son llamados.

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

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)