std:: exit
|
Défini dans l'en-tête
<cstdlib>
|
||
|
void
exit
(
int
exit_code
)
;
|
(jusqu'à C++11) | |
|
[
[
noreturn
]
]
void
exit
(
int
exit_code
)
;
|
(depuis C++11) | |
Provoque la terminaison normale du programme.
Plusieurs étapes de nettoyage sont effectuées :
|
1)
Les objets avec durée de stockage statique sont détruits et les fonctions enregistrées en appelant
std::atexit
sont appelées :
a)
Les objets non locaux avec durée de stockage statique sont détruits dans l'ordre inverse de l'achèvement de leur constructeur.
b)
Les fonctions enregistrées avec
std::atexit
sont appelées dans l'ordre inverse de leur enregistrement, sauf qu'une fonction est appelée après toute fonction précédemment enregistrée qui avait déjà été appelée au moment de son enregistrement.
c)
Pour chaque fonction
f
enregistrée avec
std::atexit
et chaque objet non local
obj
de durée de stockage statique,
d)
Pour chaque objet local
obj
avec durée de stockage statique,
obj
est détruit comme si une fonction appelant le destructeur de
obj
était enregistrée avec
std::atexit
à l'achèvement du constructeur de
obj
.
|
(jusqu'à C++11) |
|
1)
Les destructeurs des objets avec durée de stockage
thread local
qui sont associés au thread actuel, les destructeurs des objets avec durée de stockage statique, et les fonctions enregistrées avec
std::atexit
sont exécutés concurremment, tout en maintenant les garanties suivantes :
a)
Le dernier destructeur pour les objets thread-local est
séquencé-avant
le premier destructeur pour un objet statique.
b)
Si l'achèvement du constructeur ou de l'
initialisation dynamique
pour l'objet thread-local ou statique A était séquencé-avant l'objet thread-local ou statique B, l'achèvement de la destruction de B est séquencé-avant le début de la destruction de A.
c)
Si l'achèvement de l'initialisation d'un objet statique A était séquencé-avant l'appel à
std::atexit
pour une fonction F, l'appel à F pendant la terminaison est séquencé-avant le début de la destruction de A.
d)
Si l'appel à
std::atexit
pour une fonction F était séquencé-avant l'achèvement de l'initialisation d'un objet statique A, le début de la destruction de A est séquencé-avant l'appel à F pendant la terminaison.
e)
Si un appel à
std::atexit
pour une fonction F1 était séquencé-avant l'appel à
std::atexit
pour une fonction F2, alors l'appel à F2 pendant la terminaison est séquencé-avant l'appel à F1.
|
(depuis C++11) |
-
- Dans ce qui précède,
-
-
Si une fonction enregistrée avec
atexitou tout destructeur d'objet statique/local de thread lève une exception, std::terminate est appelé. - Si le compilateur a choisi de remonter l'initialisation dynamique d'un objet à la phase d'initialisation statique de l'initialisation non-locale , l'ordonnancement de la destruction respecte son initialisation dynamique potentielle.
- Si un objet statique local à une fonction (portée de bloc) a été détruit et que cette fonction est ensuite appelée depuis le destructeur d'un autre objet statique et que le flux de contrôle passe par la définition de cet objet (ou s'il est utilisé indirectement, via un pointeur ou une référence), le comportement est indéfini.
- Si un objet statique local à une fonction (portée de bloc) a été initialisé pendant la construction d'un sous-objet d'une classe ou d'un tableau, il n'est détruit qu'après que tous les sous-objets de cette classe ou tous les éléments de ce tableau aient été détruits.
-
Si une fonction enregistrée avec
exit_code
vaut
0
ou
EXIT_SUCCESS
, un statut défini par l'implémentation indiquant une terminaison réussie est retourné. Si
exit_code
vaut
EXIT_FAILURE
, un statut défini par l'implémentation indiquant une terminaison échouée est retourné. Dans les autres cas, une valeur de statut définie par l'implémentation est retournée.
La pile n'est pas déroulée : les destructeurs des variables à durée de stockage automatique ne sont pas appelés.
Table des matières |
Relation avec la fonction main
Le retour de la
fonction main
, soit par une instruction
return
soit en atteignant la fin de la fonction, effectue la terminaison normale de la fonction (appelle les destructeurs des variables avec
durée de stockage automatique
) puis exécute
std::exit
, en passant l'argument de l'instruction return (ou
0
si un retour implicite était utilisé) comme
exit_code
.
Paramètres
| exit_code | - | statut de sortie du programme |
Valeur de retour
(aucun)
Exemple
#include <cstdlib> #include <iostream> struct Static { ~Static() { std::cout << "Static destructor\n"; } }; struct Local { ~Local() { std::cout << "Local destructor\n"; } }; Static static_variable; // Le destructeur de cet objet *sera* appelé void atexit_handler() { std::cout << "atexit handler\n"; } int main() { Local local_variable; // Le destructeur de cet objet *ne sera pas* appelé const int result = std::atexit(atexit_handler); // Le gestionnaire sera appelé 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"; }
Sortie :
test atexit handler Static destructor
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement tel que publié | Comportement corrigé |
|---|---|---|---|
| LWG 3 | C++98 |
pendant le nettoyage, le comportement n'était pas clair quand (1) une fonction est
enregistrée avec std::atexit ou (2) un objet local statique est initialisé |
clarifié |
Voir aussi
|
provoque la fin anormale du programme (sans nettoyage)
(fonction) |
|
|
enregistre une fonction à appeler lors de l'invocation de
std::exit()
(fonction) |
|
|
(C++11)
|
provoque la fin rapide du programme sans nettoyage complet
(fonction) |
|
(C++11)
|
enregistre une fonction à appeler lors de l'invocation de
std::quick_exit
(fonction) |
|
Documentation C
pour
exit
|
|