Destruktor eines statischen Objekts, das im Destruktor eines anderen statischen Objekts erstellt wurde

8

Ich habe einige Probleme mit dem Destruktor, im nächsten Code:

%Vor%

Warum wurde der Destruktor für foo2 nicht für bionic aufgerufen und war für glibc ?

BEARBEITEN
Ausgabe für bionische:

%Vor%

Debug-Info:

%Vor%     
Arseniy 11.01.2013, 12:14
quelle

4 Antworten

6

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:

  1. 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.

  2. 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.

  3. 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.

    
James Kanze 11.01.2013, 12:53
quelle
5

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.

    
Stephane Rolland 11.01.2013 12:18
quelle
4

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.

    
billz 11.01.2013 12:26
quelle
4
  

C ++ 11 3.6.3 / 1: Destruktoren für initialisierte Objekte [...] mit statischer Speicherdauer werden als Ergebnis der Rückgabe von main

aufgerufen

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.

    
Mike Seymour 11.01.2013 12:51
quelle

Tags und Links