Following up on this question about multiple (virtual) inheritance, I'd like to inquire about a simple MWE that makes g++ 5.2.0 upset whereas clang++ 3.6.2 handles it just fine, with no complaints at all, even with -Wall
and -Wextra
set. So here's the MWE:
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; }
Unlike clang++, g++ complains like this:
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{} {} };
^
Replacing the uniform initialization in C's constructor with the old form works fine though and both clang++ and g++ are happy with the following:
class C : A, B { public: C() : A(), B() {} };
This yields the two obvious options:
- The code violates the standard in some way, making the outcome undefined (i.e., any outcome would be acceptable).
- One of the two compilers has a bug related to uniform initialization and multiple + virtual inheritance.
If it were a matter of voting, (1) might win, because icpc 15.0.0 says the following:
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{} {} };
^
So, is it (1) or (2)? And if it's the former case, then what's wrong with my MWE?