Diferencia entre revisiones de «cpp/utility/program/exit»
De cppreference.com
m (s/Produce/Causa) |
m (mejoras) |
||
Línea 3: | Línea 3: | ||
{{dcl begin}} | {{dcl begin}} | ||
{{dcl header | cstdlib}} | {{dcl header | cstdlib}} | ||
− | {{dcl rev | + | {{dcl rev | =c++11 | |
− | + | ||
void exit( int exit_code ); | void exit( int exit_code ); | ||
− | + | | = | |
− | + | ||
[[noreturn]] void exit( int exit_code ); | [[noreturn]] void exit( int exit_code ); | ||
}} | }} | ||
− | |||
{{dcl end}} | {{dcl end}} | ||
− | + | la terminación normal del programa. | |
Se realizan varios pasos de limpieza: | Se realizan varios pasos de limpieza: | ||
− | {{ | + | {{|=c++11 |
− | + | | | |
@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 [[cpp/language/initialization#Inicialización_dinámica|inicialización dinámica]], y las funciones pasadas a {{lc|std::atexit}} se llaman en orden inverso al que están registradas (primero la última). | @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 [[cpp/language/initialization#Inicialización_dinámica|inicialización dinámica]], y las funciones pasadas a {{lc|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 {{lc|std::atexit}} para alguna función F se destruirá después de la llamada a F durante la finalización del programa. | + | :@a@ Cualquier objeto estático cuya inicialización se completó antes de la llamada a {{lc|std::atexit}} para alguna función Fse 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 {{lc|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 {{lc|std::atexit}} fue llamada desde el constructor del objeto estático). | + | :@b@ Cualquier objeto estático cuya construcción comenzó después de la llamada a {{lc|std::atexit}} para alguna función Fse destruirá antes de la llamada a F durante la finalización del programa (esto incluye el caso donde {{lc|std::atexit}} fue llamada desde el constructor del objeto estático). |
− | + | |= | |
− | + | ||
@1@ Los destructores de objetos con [[cpp/language/storage duration|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 {{lc|std::atexit}} se ejecutan simultáneamente, manteniendo las siguientes garantías: | @1@ Los destructores de objetos con [[cpp/language/storage duration|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 {{lc|std::atexit}} se ejecutan simultáneamente, manteniendo las siguientes garantías: | ||
:@a@ El último destructor para objetos locales al hilo es [[cpp/language/eval order|secuenciado-antes]] del primer destructor para un objeto estático. | :@a@ El último destructor para objetos locales al hilo es [[cpp/language/eval order|secuenciado-antes]] del primer destructor para un objeto estático. | ||
Línea 29: | Línea 25: | ||
:@c@ Si la finalización de la inicialización de un objeto estático A fue secuenciada-antes de la llamada a {{lc|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. | :@c@ Si la finalización de la inicialización de un objeto estático A fue secuenciada-antes de la llamada a {{lc|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 {{lc|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. | :@d@ Si la llamada a {{lc|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 {{lc|std::atexit}} para alguna función F1 fue secuenciada-antes de la llamada a {{lc|std::atexit}} para alguna función F2, entonces la llamada a F2 durante la terminación es secuenciada-antes de la llamada a F1}} | + | :@e@ Si una llamada a {{lc|std::atexit}} para alguna función F1 fue secuenciada-antes de la llamada a {{lc|std::atexit}} para alguna función F2, entonces la llamada a F2 durante la terminación es secuenciada-antes de la llamada a F1}} |
− | + | ||
− | :* | + | :* , |
::* Si cualquier función registrada con {{tt|atexit}} o cualquier destructor de un objeto estático o local al hilo lanza una excepción, se llama a {{lc|std::terminate}}. | ::* Si cualquier función registrada con {{tt|atexit}} o cualquier destructor de un objeto estático o local al hilo lanza una excepción, se llama a {{lc|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 [[cpp/language/initialization|inicialización no local]], el secuenciado de destrucción cumple con lo que sería su inicialización dinámica. | ::* Si el compilador optó por levantar la inicialización dinámica de un objeto a la fase de inicialización estática de la [[cpp/language/initialization|inicialización no local]], el secuenciado de destrucción cumple con lo que sería su inicialización dinámica. | ||
Línea 43: | Línea 39: | ||
===Relación con la función {{tt|main}}=== | ===Relación con la función {{tt|main}}=== | ||
− | Retornar de la [[cpp/language/main function|función {{tt|main}}]], ya sea por una instrucción {{tt|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 [[cpp/language/storage duration|duraciones de almacenamiento]] automática y luego ejecuta {{ | + | Retornar de la [[cpp/language/main function|función {{tt|main}}]], ya sea por una instrucción {{tt|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 [[cpp/language/storage duration|duraciones de almacenamiento]] automática y luego ejecuta {{|std::exit}}, pasando el argumento a la instrucción {{tt|return}} (o {{c|0}} si se utilizó {{tt|return}} implícito) como el código de salida ({{tt|exit_code}}). |
===Parámetros=== | ===Parámetros=== | ||
Línea 60: | Línea 56: | ||
#include <cstdlib> | #include <cstdlib> | ||
− | + | Static { | |
− | + | ||
− | + | ||
~Static() | ~Static() | ||
{ | { | ||
− | std::cout << " | + | std::cout << "Static \n"; |
} | } | ||
}; | }; | ||
− | + | Local { | |
− | + | ||
~Local() | ~Local() | ||
{ | { | ||
− | std::cout << " | + | std::cout << "Local \n"; |
} | } | ||
}; | }; | ||
− | Static | + | Static ; // se llamará al destructor de este objeto |
void atexit_handler() | void atexit_handler() | ||
Línea 96: | Línea 89: | ||
std::cout << "prueba\n"; | std::cout << "prueba\n"; | ||
std::exit(EXIT_FAILURE); | std::exit(EXIT_FAILURE); | ||
+ | |||
+ | |||
} | } | ||
| output= | | output= | ||
prueba | prueba | ||
controlador atexit | controlador atexit | ||
− | + | Static | |
}} | }} | ||
Última revisión de 08:33 20 ene 2021
Definido en el archivo de 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 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) |
- En lo descrito anteriormente,
- 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 |
[editar] 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
).
[editar] Parámetros
exit_code | - | Estatus de salida del programa. |
[editar] Valor de retorno
(Ninguno)
[editar] Ejemplo
Ejecuta este código
#include <iostream> #include <cstdlib> struct Static { ~Static() { std::cout << "Static dtor\n"; } }; struct Local { ~Local() { std::cout << "Local dtor\n"; } }; Static variable_estatica; // 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); std::cout << "esta línea no se ejecutará\n"; }
Salida:
prueba controlador atexit Static dtor
[editar] 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
|