Diferencia entre revisiones de «cpp/utility/program/exit»
De cppreference.com
m (Cosméticos) |
m (s/Produce/Causa) |
||
Línea 13: | Línea 13: | ||
{{dcl end}} | {{dcl end}} | ||
− | + | que ocurra la terminación normal del programa. | |
Se realizan varios pasos de limpieza: | Se realizan varios pasos de limpieza: |
Revisión de 05:59 29 mar 2020
Definido en el archivo de encabezado <cstdlib>
|
||
void exit( int exit_code ); |
(hasta C++11) | |
[[noreturn]] void exit( int exit_code ); |
(desde C++11) | |
Causa que ocurra la terminación normal del programa.
Se realizan varios pasos de limpieza:
1) Los destructores de objetos con una duración de almacenamiento estática se llaman en orden inverso a la finalización de sus constructores o la finalización de su inicialización dinámica, y las funciones pasadas a std::atexit se llaman en orden inverso al que están registradas (primero la última).
a) Cualquier objeto estático cuya inicialización se completó antes de la llamada a std::atexit para alguna función F se destruirá después de la llamada a F durante la finalización del programa.
b) Cualquier objeto estático cuya construcción comenzó después de la llamada a std::atexit para alguna función F se destruirá antes de la llamada a F durante la finalización del programa (esto incluye el caso donde std::atexit fue llamada desde el constructor del objeto estático).
|
(hasta C++11) |
1) Los destructores de objetos con duración de almacenamiento local al hilo que están asociados con el hilo actual, los destructores de objetos con duración de almacenamiento estática y las funciones registradas con std::atexit se ejecutan simultáneamente, manteniendo las siguientes garantías:
a) El último destructor para objetos locales al hilo es secuenciado-antes del primer destructor para un objeto estático.
b) Si la finalización del constructor o inicialización dinámica para el objeto local al hilo o estático A fue secuenciada-antes del objeto local al hilo o estático B, la finalización de la destrucción de B es secuenciada-antes del comienzo de la destrucción de A.
c) Si la finalización de la inicialización de un objeto estático A fue secuenciada-antes de la llamada a std::atexit para alguna función F, la llamada a F durante la terminación será secuenciada-antes del inicio de la destrucción de A.
d) Si la llamada a std::atexit para alguna función F fue secuenciada-antes de completar la inicialización de un objeto estático A, el inicio de la destrucción de A es secuenciado-antes de la llamada a F durante la terminación.
e) Si una llamada a std::atexit para alguna función F1 fue secuenciada-antes de la llamada a std::atexit para alguna función F2, entonces la llamada a F2 durante la terminación es secuenciada-antes de la llamada a F1 |
(desde C++11) |
- Arriba,
- Si cualquier función registrada con
atexit
o cualquier destructor de un objeto estático o local al hilo lanza una excepción, se llama a std::terminate. - Si el compilador optó por levantar la inicialización dinámica de un objeto a la fase de inicialización estática de la inicialización no local, el secuenciado de destrucción cumple con lo que sería su inicialización dinámica.
- Si un objeto estático local a una función (en contexto de bloque) se destruyó y luego esa función se llama 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 es utilizado indirectamente, mediante un puntero o una referencia), el comportamiento es indefinido.
- Si un objeto estático local a una función (en contexto de bloque) se inicializó durante la construcción de un subobjeto de una clase o array, se destruye solamente después de que todos los subobjetos de esa clase o todos los elementos de ese array se destruyen.
- Si cualquier función registrada con
2) Todos los flujos de C se vacían y se 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 estatus definido por la implementación que indica terminación con éxito. Si exit_code
es EXIT_FAILURE, se devuelve un estatus definido por la implementación que indica terminación sin éxito. En los otros casos se devuelve un valor de estatus definido por la implementación.La pila no se desenreda: no se llama a los destructores de variables con duración de almacenamiento automática.
Contenido |
Relación con la función main
Retornar de la función main
, ya sea por una instrucción return
o al alcanzar el final de la función realiza una terminación normal de la función (llama a los destructores de las variables con duraciones de almacenamiento automática y luego ejecuta std::exit, pasando el argumento a la instrucción return
(o 0 si se utilizó return
implícito) como el código de salida (exit_code
).
Parámetros
exit_code | - | Estatus de salida del programa. |
Valor de retorno
(Ninguno)
Ejemplo
Ejecuta este código
#include <iostream> #include <cstdlib> class Static { public: ~Static() { std::cout << "destructor de Static\n"; } }; class Local { public: ~Local() { std::cout << "destructor de Local\n"; } }; Static static_variable; // se llamará al destructor de este objeto void atexit_handler() { std::cout << "controlador atexit\n"; } int main() { Local local_variable; // no se llamará al destructor de este objeto const int result = std::atexit(atexit_handler); // se llamará al controlador if (result != 0) { std::cerr << "falla al registrarse con atexit\n"; return EXIT_FAILURE; } std::cout << "prueba\n"; std::exit(EXIT_FAILURE); }
Salida:
prueba controlador atexit destructor de Static
Véase también
Produce la terminación anormal del programa (sin limpiar). (función) | |
Registra una función a ser llamada cuando se invoque a exit(). (función) | |
(C++11) |
Produce la terminación normal del programa sin limpiar completamente. (función) |
(C++11) |
Registra una función a ser llamada cuando se invoque a quick_exit. (función) |
Documentación de C para exit
|