2015-08-16 14 views
6

Nawiązując do this question about multiple (virtual) inheritance, chciałbym zapytać o prostym MWE sprawia, że ​​g ++ 5.2.0 zdenerwowany, natomiast szczęk ++ 3.6.2 obsługuje po prostu w porządku, bez skarg na wszystko, nawet z zestawem -Wall i -Wextra. Tak oto MWE:wirtualnej spadków i jednolity inicjalizacji w C++

class Z {}; 
class A : virtual Z { protected: A() {} }; 
class B : virtual Z { protected: B() {} }; 
class C : A, B { public: C() : A{}, B{} {} }; 
int main() { C c{}; return 0; } 

przeciwieństwie brzękiem ++ g ++ narzeka tak:

gccodd.c++: In constructor ‘C::C()’: 
gccodd.c++:2:34: error: ‘A::A()’ is protected 
class A : virtual Z { protected: A() {} }; 
           ^
gccodd.c++:4:39: error: within this context 
class C : A, B { public: C() : A{}, B{} {} }; 
            ^
gccodd.c++:3:34: error: ‘B::B()’ is protected 
class B : virtual Z { protected: B() {} }; 
           ^
gccodd.c++:4:39: error: within this context 
class C : A, B { public: C() : A{}, B{} {} }; 
            ^

Wymiana jednolitej inicjalizacji w konstruktora C jest ze starej formy działa dobrze choć i zarówno dzyń ++ i g ++ są zadowoleni z następujące:

class C : A, B { public: C() : A(), B() {} }; 

daje to dwie wyraźne opcje:

  1. Kodeks narusza standard w pewien sposób, przez co jego wynik jest niezdefiniowany (tj. Każdy wynik jest akceptowalny).
  2. Jeden z dwóch kompilatorów ma błąd związany z jednolitą inicjalizacją i wieloma dziedziczeniami + wirtualnymi.

Gdyby to była kwestia głosowania (1) może wygrać, bo ICPC 15.0.0 mówi co następuje:

gccodd.c++(4): error #453: protected function "A::A()" (declared at line 2) is not accessible through a "A" pointer or object 
    class C : public virtual A, public virtual B { public: C() : A{}, B{} {} }; 
                   ^

gccodd.c++(4): error #453: protected function "B::B()" (declared at line 3) is not accessible through a "B" pointer or object 
    class C : public virtual A, public virtual B { public: C() : A{}, B{} {} }; 
                    ^

tak, to on (1) lub (2)? A jeśli to pierwszy przypadek, to co jest nie tak z moim MWE?

+0

Brzmi jak błąd. Nie ma powodu, by sądzić, że tu będzie UB. –

+0

VC++ 14.0 również to kompiluje, chociaż IntelliSense narzeka na to. – Fireho

+2

GCC jest błędny, jeśli chodzi o [inicjowanie agregacji klas podstawowych w inicjatorze pamięci] (http://coliru.stacked-crooked.com/a/8c60d42406381caa). – 0x499602D2

Odpowiedz

5

Lista inicjalizacja obiektu lub odniesienia typu T jest zdefiniowana jako następująco:
(3.1), - jeśli T to typ klasy, lista inicjatora ma jeden element typu cvU [ ..]
(3.2) - W przeciwnym razie, jeśli T jest tablicą znaków [..]
(3.3) - W przeciwnym razie, jeśli T jest agregatem, przeprowadzana jest inicjacja agregacji (8.5.1).
(3.4) - W przeciwnym razie, jeśli lista inicjalizatorów nie ma elementów, a T jest typem klasy z domyślnym konstruktorem , obiekt jest inicjowany wartością.

A i B oba mają klas bazowych, a więc nie są kruszywa. Zatem obowiązuje czwarty punkt punktowy. I w ten sposób mają dokładnie ten sam efekt, jak gdyby to była używana ():

Przedmiotem których inicjator jest zbiorem pustym z nawiasach, to (), są wartości inicjalizacji.

Nie można zastosować żadnego kompilatora dającego różne wyniki z tymi inicjalizatorami.

§11.4, który obsługuje dostęp do członków protected, nie wspomina o niczym związanym z formą inicjalizacji.Jednak w odniesieniu do inicjowania baz w inicjatorze pamięci w konstruktorze, § 11.4 jest wadliwy w chwili obecnej, jak wspomniano w wydaniu CWG #1883.

+0

Dzięki za wskazanie dokładnej części standardu opisującego tę sprawę. Wygląda więc na to, że kompilator Intel/"composer" traktuje swoją kompatybilność z GCC nieco zbyt poważnie, wprowadzając również błędy GCC. :-) Co do błędów w standardzie, ostatnio zauważyłem [to pytanie dotyczące referencji i jednolitej inicjalizacji] (http://stackoverflow.com/questions/10509603/why-cant-i-initialize-a-reference-in -an-initializer-list-with-uniform-initializ). Zasadniczo transpozycja 2 punktorów w standardzie otworzyła 3-letnie okno kompilatorów buggy (w pewnym sensie). – user1715611