std:: exit
|
Definiert im Header
<cstdlib>
|
||
|
void
exit
(
int
exit_code
)
;
|
(bis C++11) | |
|
[
[
noreturn
]
]
void
exit
(
int
exit_code
)
;
|
(seit C++11) | |
Verursacht das normale Beenden des Programms.
Es werden mehrere Bereinigungsschritte durchgeführt:
|
1)
Objekte mit statischer Speicherdauer werden zerstört und Funktionen, die durch Aufruf von
std::atexit
registriert wurden, werden aufgerufen:
a)
Nicht-lokale Objekte mit statischer Speicherdauer werden in umgekehrter Reihenfolge zur Vollendung ihrer Konstruktoren zerstört.
b)
Mit
std::atexit
registrierte Funktionen werden in umgekehrter Reihenfolge ihrer Registrierung aufgerufen, außer dass eine Funktion nach allen bereits registrierten Funktionen aufgerufen wird, die zum Zeitpunkt ihrer Registrierung bereits aufgerufen worden waren.
c)
Für jede Funktion
f
, die mit
std::atexit
registriert wurde, und jedes nicht-lokale Objekt
obj
mit statischer Speicherdauer gilt:
d)
Für jedes lokale Objekt
obj
mit statischer Speicherdauer wird
obj
zerstört, als ob eine Funktion, die den Destruktor von
obj
aufruft, bei Vollendung des Konstruktors von
obj
mit
std::atexit
registriert worden wäre.
|
(bis C++11) |
|
1)
Die Destruktoren von Objekten mit
Thread-lokaler Speicherdauer
, die dem aktuellen Thread zugeordnet sind, die Destruktoren von Objekten mit statischer Speicherdauer und die mit
std::atexit
registrierten Funktionen werden gleichzeitig ausgeführt, wobei folgende Garantien bestehen:
a)
Der letzte Destruktor für Thread-lokale Objekte ist
sequenziert-vor
dem ersten Destruktor für ein statisches Objekt.
b)
Wenn die Vollendung des Konstruktors oder der
dynamischen Initialisierung
für Thread-lokales oder statisches Objekt A sequenziert-vor Thread-lokalem oder statischem Objekt B war, ist die Vollendung der Zerstörung von B sequenziert-vor dem Beginn der Zerstörung von A.
c)
Wenn die Vollendung der Initialisierung eines statischen Objekts A sequenziert-vor dem Aufruf von
std::atexit
für eine Funktion F war, ist der Aufruf von F während der Beendigung sequenziert-vor dem Beginn der Zerstörung von A.
d)
Wenn der Aufruf von
std::atexit
für eine Funktion F sequenziert-vor der Vollendung der Initialisierung eines statischen Objekts A war, ist der Beginn der Zerstörung von A sequenziert-vor dem Aufruf von F während der Beendigung.
e)
Wenn ein Aufruf von
std::atexit
für eine Funktion F1 sequenziert-vor dem Aufruf von
std::atexit
für eine Funktion F2 war, dann ist der Aufruf von F2 während der Beendigung sequenziert-vor dem Aufruf von F1.
|
(seit C++11) |
-
- Im obigen Text,
-
-
Wenn eine mit
atexitregistrierte Funktion oder ein Destruktor eines statischen/thread-lokalen Objekts eine Exception wirft, std::terminate wird aufgerufen. - Wenn der Compiler sich entscheidet, die dynamische Initialisierung eines Objekts in die statische Initialisierungsphase der nicht-lokalen Initialisierung zu verlagern, berücksichtigt die Reihenfolge der Zerstörung deren dynamische Initialisierung.
- Wenn ein funktionslokales (Blockbereich) statisches Objekt zerstört wurde und dann diese Funktion aus dem Destruktor eines anderen statischen Objekts aufgerufen wird und der Kontrollfluss durch die Definition dieses Objekts verläuft (oder wenn es indirekt, über Zeiger oder Referenz, verwendet wird), ist das Verhalten undefiniert.
- Wenn ein funktionslokales (Blockbereich) statisches Objekt während der Konstruktion eines Subobjekts einer Klasse oder eines Arrays initialisiert wurde, wird es erst zerstört, nachdem alle Subobjekte dieser Klasse oder alle Elemente dieses Arrays zerstört wurden.
-
Wenn eine mit
exit_code
gleich
0
oder
EXIT_SUCCESS
ist, wird ein implementierungsdefinierter Status zurückgegeben, der eine erfolgreiche Beendigung anzeigt. Wenn
exit_code
gleich
EXIT_FAILURE
ist, wird ein implementierungsdefinierter Status zurückgegeben, der eine erfolglose Beendigung anzeigt. In anderen Fällen wird ein implementierungsdefinierter Statuswert zurückgegeben.
Der Stack wird nicht abgewickelt: Destruktoren von Variablen mit automatischer Speicherdauer werden nicht aufgerufen.
Inhaltsverzeichnis |
Beziehung zur main-Funktion
Die Rückkehr von der
main-Funktion
, entweder durch eine
return
-Anweisung oder durch das Erreichen des Funktionsendes, führt die normale Funktionsbeendigung durch (ruft die Destruktoren der Variablen mit automatischer
Speicherdauer
auf) und führt dann
std::exit
aus, wobei das Argument der return-Anweisung (oder
0
bei impliziter Rückgabe) als
exit_code
übergeben wird.
Parameter
| exit_code | - | Exit-Status des Programms |
Rückgabewert
(keine)
Beispiel
#include <cstdlib> #include <iostream> struct Static { ~Static() { std::cout << "Static destructor\n"; } }; struct Local { ~Local() { std::cout << "Local destructor\n"; } }; Static static_variable; // Destruktor dieses Objekts *wird* aufgerufen void atexit_handler() { std::cout << "atexit handler\n"; } int main() { Local local_variable; // Destruktor dieses Objekts wird *nicht* aufgerufen const int result = std::atexit(atexit_handler); // Handler wird aufgerufen 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"; }
Ausgabe:
test atexit handler Static destructor
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 3 | C++98 |
während des Cleanups war das Verhalten unklar, wenn (1) eine Funktion mit
std::atexit registriert wird oder (2) ein statisches lokales Objekt initialisiert wird |
klargestellt |
Siehe auch
|
verursacht abnormale Programmbeendigung (ohne Bereinigung)
(Funktion) |
|
|
registriert eine Funktion, die beim Aufruf von
std::exit()
aufgerufen wird
(Funktion) |
|
|
(C++11)
|
verursacht schnelle Programmbeendigung ohne vollständige Bereinigung
(Funktion) |
|
(C++11)
|
registriert eine Funktion, die beim Aufruf von
std::quick_exit
aufgerufen wird
(Funktion) |
|
C-Dokumentation
für
exit
|
|