std:: exit
|
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,
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
atexito 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.
-
Si cualquier función registrada con
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) |
|
(C++11)
|
registra una función para ser llamada al invocar
std::quick_exit
(función) |
|
Documentación de C
para
exit
|
|