2013-07-22 5 views
9

Minimal Codebeispiel:C++ 11 „In der Klasse Initialisierung“ Feature funktioniert nicht für die Gewerkschaften

struct B { 
    union U { 
    struct S {} s; 
    int i = 100; 
    } 
    u; 
}; 

Wenn wir nun ein B obj; erklären dann die obj.u.i einen Müll Wert statt 100 zugeordnet ist. Siehe demo here. (Der Müllwert unterscheidet sich basierend auf Optimierungsflags usw.).

Die Funktion "In Klasseninitialisierung" soll mit Unionen arbeiten.

  • Wenn ja, wie lautet die richtige Syntax? Oder ist das ein g ++ Bug?
  • Wenn nicht was dann int i = 100; tut?
+1

+1 Gute Frage. – Nawaz

+2

[clang] (http://coliru.stacked-crooked.com/view?id=6ab1a0f46b2229dfc46dfa6f4f5e3163-6e9f1f680880347f6708b805c806db62) scheint mit Ihrem Code zufrieden zu sein. – Praetorian

+0

@Praetorian, Danke. Sie haben jedoch die Ausgabeanweisungen nicht ausgegeben. Also hier ist die korrekte [clang output] (http://coliru.stacked-crooked.com/view?id=542928082d0e3f7d6edd525a7fcfac44-6e9f1f680880347f6708b805c806db62). – iammilind

Antwort

3

Das sieht wie ein GCC-Bug aus. Der Standard sagt (9.5p2):

At most one non-static data member of a union may have a brace-or-equal-initializer.

Ansonsten sind die Regeln die gleichen wie für eine reguläre Klasse.

EDIT: Außerdem 12.6.2p8:

In a non-delegating constructor, if a given non-static data member or base class is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer) and the entity is not a virtual base class of an abstract class (10.4), then

  • if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initialized as specified in 8.5;
  • otherwise, if the entity is a variant member (9.5), no initialization is performed;
  • otherwise, the entity is default-initialized (8.5).

Vermutlich ist die implizit Standardkonstruktors definiert zählt hier. Das i Mitglied erfüllt die Kriterien im ersten Aufzählungspunkt, so dass es wie ein reguläres Klassenmitglied initialisiert wird. Das Element s entspricht dem zweiten Aufzählungspunkt, sodass es nicht initialisiert ist.

+0

Jede Lösung mit dem aktuellen Code? – iammilind

+0

Es kompiliert nicht auf VS 2010 & 2012, nicht einmal die erste Version, mit dem Fehler: nur statische const integral Datenelemente können innerhalb einer Klasse initialisiert werden. Oder beide Compiler haben einen Fehler oder es gibt etwas mehr ... – neagoegab

+0

@neagoegab Keine dieser VS-Versionen unterstützt die Initialisierung von Datenmembern in der Klasse. [clang] (http://coliru.stacked-crooked.com/view?id=6ab1a0f46b2229dfc46dfa6f4f5e3163-6e9f1f680880347f6708b805c806db62) kompiliert den Code ohne Fehler. – Praetorian

2

Ich denke es ist so, weil eine Gewerkschaft mehr als ein Element vereint. Unten ist die Arbeit um Syntax:

struct B { 
    union U { 
    int i; 
    } 
    u {100}; 
}; 

int main() { 
    B obj; 
    std::cout << "obj.u.i = " << obj.u.i << "\n"; 
} 
+1

Bitte hör auf zu raten. Hinterlegen Sie eine Antwort, die Sie * kennen * und unterstützen können. – Nawaz

+0

@Nawaz, ich glaube, dass ich meine Antwort unterstützt habe. Die Alternative ist, es im Standard zu finden, aber dabei bist du schneller als ich: D, aber ich werde die Antwort aktualisieren. – neagoegab

+0

Diese Lösung funktioniert nicht mit meinem eigentlichen Problem, fügen Sie einfach 'struct S {} s;' innerhalb der 'Union U' und das Programm gibt [Compiler-Fehler] (http://ideone.com/5tS7q9). Ich habe die Frage entsprechend aktualisiert. – iammilind

Verwandte Themen