Namespaces
Variants

std:: exit

From cppreference.net
Utilities library
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:
  • wenn f vor der Initialisierung von obj registriert wurde, wird f erst nach der Zerstörung von obj aufgerufen;
  • wenn f nach der Initialisierung von obj registriert wurde, wird f vor der Zerstörung von obj aufgerufen.
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 atexit registrierte 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.
2) Alle C-Streams werden geleert und geschlossen.
3) Von std::tmpfile erstellte Dateien werden entfernt.
4) Die Steuerung wird an die Host-Umgebung zurückgegeben. Wenn 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)
registriert eine Funktion, die beim Aufruf von std::quick_exit aufgerufen wird
(Funktion)