Behält die C ++ - Standardinitialisierung die vorherige Nullinitialisierung bei?

8

Wenn ein C ++ - Konstruktor für ein Objekt mit statischer Speicherdauer ein Member nicht initialisiert, ist das erforderlich, um die vorherige Nullinitialisierung beizubehalten, oder belässt es das Element mit einem unbestimmten Wert?

Mein Lesen der C ++ - Spezifikation ist, dass es sich widerspricht.

Beispiel:

%Vor%

Der Konstruktor Foo () initialisiert das Member object.x nicht explizit entsprechend der Anmerkung in 12.6.2 Absatz 8:

  

das Mitglied hat einen unbestimmten Wert.

Aber durch die Details der verschiedenen Initialisierungen scheint dies zu funktionieren falsch sein. Das Element object.x wird auf Null initialisiert, da es statische Speicherdauer hat, und dann kann ich nichts sehen, was das ändert.

Bezüglich des Konstruktors gilt der folgende Text in 12.6.2:

  

Die Entität wird standardmäßig initialisiert.

In 8.5 Absatz 7 ist der relevante Fall der Standardinitialisierung:

  

... es wird keine Initialisierung durchgeführt

was ich gelesen habe bedeutet, dass die vorherige Null-Initialisierung nicht durch die Standard-Initialisierung geändert wurde.

Vermisse ich einen anderen Text, der alle Mitglieder am Beginn des Konstruktoraufrufs auf "unbestimmter Wert" zurücksetzt?

Ich habe verschiedene andere Fragen zu Stackoverflow bezüglich Null-Initialisierung und gefunden Standard-Initialisierung, aber das konnte ich nicht sehen analysiert, was passiert, wenn die Standard-Initialisierung folgt einige frühe Initialisierung der gleichen Entität.

In diesem Fall gibt es wahrscheinlich keinen praktischen Effekt. Aber muss der Compiler in einem komplexeren Konstruktor, bei dem einige Member initialisiert wurden und andere nicht, genau nachverfolgen, welche Bytes / Bits initialisiert wurden? Oder kann er das ganze Objekt initialisieren (zB den Konstruktor zu einem memset () - Aufruf vereinfachen) )?

    
user1998586 31.10.2015, 20:17
quelle

1 Antwort

3

Fehlerbericht 1787 führte zu der in N3914 ist angewandt auf den Entwurf des Standards für C ++ 14 . Welche Änderung [dcl.init] Absatz 12 von:

  

Wenn für ein Objekt kein Initialisierer angegeben ist, ist das Objekt   Standard-initialisiert; Wenn keine Initialisierung durchgeführt wird, ein Objekt mit   Die automatische oder dynamische Speicherdauer hat einen unbestimmten Wert. [ Hinweis:   Objekte mit statischer oder Thread-Speicherdauer werden initialisiert,   siehe 3.6.2. - Endnote]

zu:

  

Wenn für ein Objekt kein Initialisierer angegeben ist, ist das Objekt   Standardinitialisiert Beim Speichern eines Objekts mit automatischer oder   dynamische Speicherdauer wird erhalten, das Objekt hat eine unbestimmte   Wert, und wenn keine Initialisierung für das Objekt durchgeführt wird   Objekt behält einen unbestimmten Wert bei, bis dieser Wert ersetzt wird   (5.17 [Ausdruck]). [Hinweis: Objekte mit statischem oder Thread-Speicher   Dauer ist null-initialisiert, siehe 3.6.2 [basic.start.init]. -Ende   note] Wird durch eine Auswertung ein unbestimmter Wert erzeugt, so wird der   Verhalten ist nicht definiert, außer in den folgenden Fällen:

     

[...]

Dadurch wird deutlich, dass die unbestimmte Wertesituation nur bei Objekten mit automatischer oder dynamischer Speicherdauer auftritt. Da dies über einen Fehlerbericht angewendet wurde, gilt es wahrscheinlich auch für C ++ 11, da der Fehlerbericht vor der Übernahme von C ++ 14 aufgetreten ist, aber auch noch weiter zurückgehen könnte. Die Regeln, wie weit ein Defekt zurückgehen soll, waren mir nie klar.

Da das Placement new in den Kommentaren angezeigt wurde, hat dieselbe Änderung auch den Abschnitt [expr.new] geändert, wodurch der unbestimmte Wertteil zu einem Kommentar wurde:

  

Wenn der new-initializer weggelassen wird, wird das Objekt standardmäßig initialisiert   (8.5 [dcl.init]); ob. [Hinweis: Wenn keine Initialisierung durchgeführt wird, wird die   Objekt hat einen unbestimmten Wert. -Hinweis]

Der Anfang des Abschnitts sagt:

  

[...] Entitäten, die mit einem new-Ausdruck erstellt wurden, haben einen dynamischen Speicher   Dauer (3.7.4). [...]

Was ausreichend scheint, um die Änderungen in Abschnitt [dcl.init] anzuwenden.

Diese Änderung war auch interessant, da vor dieser Änderung der Begriff unbestimmter Wert im C ++ - Standard nicht definiert wurde

    
Shafik Yaghmour 01.11.2015, 00:08
quelle