Espacios de nombres
Variantes
Acciones

Diferencia entre revisiones de «cpp/utility/program/exit»

De cppreference.com
< cpp‎ | utility‎ | program
m (s/Produce/Causa)
m (mejoras)
 
Línea 3: Línea 3:
 
{{dcl begin}}
 
{{dcl begin}}
 
{{dcl header | cstdlib}}
 
{{dcl header | cstdlib}}
{{dcl rev begin}}
+
{{dcl rev | =c++11 |
{{dcl | until=c++11 |
+
 
             void exit( int exit_code );
 
             void exit( int exit_code );
}}
+
| =
{{dcl | since=c++11 |
+
 
[[noreturn]] void exit( int exit_code );
 
[[noreturn]] void exit( int exit_code );
 
}}
 
}}
{{dcl rev end}}
 
 
{{dcl end}}
 
{{dcl end}}
  
Causa que ocurra la terminación normal del programa.
+
la terminación normal del programa.
  
 
Se realizan varios pasos de limpieza:
 
Se realizan varios pasos de limpieza:
  
{{rev begin}}
+
{{|=c++11
{{rev|until=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).
}}
+
|=
{{rev|since=c++11|
+
 
@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}}
{{rev end}}
+
 
:* Arriba,
+
:* ,
 
::* 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 {{lc|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}}).
+
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>
  
class Static {
+
Static {
public:
+
 
+
 
     ~Static()  
 
     ~Static()  
 
     {
 
     {
         std::cout << "destructor de Static\n";
+
         std::cout << "Static \n";
 
     }
 
     }
 
};
 
};
  
class Local {
+
Local {
public:
+
 
     ~Local()  
 
     ~Local()  
 
     {
 
     {
         std::cout << "destructor de Local\n";
+
         std::cout << "Local \n";
 
     }
 
     }
 
};
 
};
  
Static static_variable; // se llamará al destructor de este objeto
+
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
destructor de Static
+
Static
 
}}
 
}}
  

Última revisión de 08:33 20 ene 2021

 
 
Biblioteca de servicios
 
Servicios de apoyo de programa
Terminación del programa
exit
(C++11)
(C++11)
Comunicación con el entorno
Señales
Tipos de señales
Saltos no locales
Tipos
 
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.
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

#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) [editar]
Registra una función a ser llamada cuando se invoque a exit().
(función) [editar]
Produce la terminación normal del programa sin limpiar completamente.
(función) [editar]
Registra una función a ser llamada cuando se invoque a quick_exit.
(función) [editar]