Ich denke, Ihr Code hat undefiniertes Verhalten, obwohl der Standard ist nicht wirklich klar darüber (oder ich finde es nicht in der Standard). Ihr Code erstellt ein neues statisches Objekt in der Destruktor eines statischen Objekts. Der Standard spricht nicht an dieser Fall, aber:
Es heißt, dass Destruktoren umgekehrt aufgerufen werden müssen
Reihenfolge der Konstruktion. In Ihrem Fall würde dies bedeuten, dass die
Das statische Objekt in GetFoo2
muss vorher zerstört werden
konstruiert, die sich widerspricht.
Der Text in §3.6 / 3 beschreibt die Reihenfolge der Destruktoren
und Funktionen, die mit atexit
registriert wurden. Die Anforderungen sind
so dass für jeden derselbe Registrierungsmechanismus verwendet werden muss.
Und ruft atexit
auf, nachdem Sie exit
aufgerufen haben (oder von
main
) ist undefiniertes Verhalten.
Es gibt auch §3.6 / 2, in dem steht: "Wenn eine Funktion enthält ein Block-Scope-Objekt mit statischer oder Thread-Speicherdauer das wurde zerstört und die Funktion wird während der aufgerufen Zerstörung eines Objekts mit statischem oder Thread-Speicher Dauer hat das Programm ein unbestimmtes Verhalten, wenn der Fluss von Kontrolle durchläuft die Definition des Vorherigen zerstörter Blockscope-Gegenstand. "Dieser Satz spricht schon von alread zerstörte Objekte, aber es braucht nicht viel Phantasie zum Nachdenken dass die Abwesenheit von "noch nicht konstruierten" Objekten nur eine ist Aufsicht.
Am Ende würde ich sagen, dass mein erster Punkt oben schlüssig ist mit in Bezug auf die Absicht. In § 1.3.24 gibt es einen Hinweis (nicht normativ, aber bezeichnend für die Absicht) "Undefiniertes Verhalten kann erwartet werden wenn dieser Internationale Standard eine explizite Definition von Verhalten oder wenn ein Programm ein fehlerhaftes Konstrukt verwendet oder fehlerhafte Daten. "In diesem Fall ist die einzige Beschreibung der erforderliches Verhalten ist unmöglich (da man ein Objekt, bevor es konstruiert wurde), und der Standard sagt nichts darüber, wie dies gelöst werden sollte.
Alle Instanzen, die ich in diesem Code sehe, sind statisch.
Folglich wird ihr Destruktor am Ende der ausführbaren Datei aufgerufen, nachdem main beendet ist.
Wenn der Destruktor nicht aufgerufen wurde, war es ein Fehler.
Das statische Objekt wird zerstört, wenn ein Programm existiert. Setzen Sie einen Unterbrechungspunkt bei ~Foo2()
, Sie werden es sehen oder Protokoll in eine Datei schreiben, sollte Ihnen helfen, es zu diagnostizieren. Wenn wirklich nicht aufgerufen, dann ist es ein Compiler Bug.
Und es macht Spaß, ein Bild hochzuladen, um eine Frage zu beantworten.
C ++ 11 3.6.3 / 1: Destruktoren für initialisierte Objekte [...] mit statischer Speicherdauer werden als Ergebnis der Rückgabe von
aufgerufenmain
An dem Punkt, an dem das Programm von main
zurückkehrt, wurde anotherFoo
initialisiert; aber foo2
hat nicht, da es erst beim ersten Aufruf von GetFoo2
während der Zerstörung von anotherFoo
initialisiert wird. Daher würde eine strenge Interpretation der Regeln bedeuten, dass der Destruktor nicht aufgerufen werden sollte.
Tags und Links c++ oop g++ static destructor