Strange default empty constructor on a virtual inheritance behaviour on GCC

Standard says (latest draft):

[class.default.ctor]

A defaulted default constructor for class X is defined as deleted if:

  • X is a union that ... [[does not apply]]
  • X is a non-union class that has a variant member M with ... [[does not apply]]
  • any non-static data member with no default member initializer ([class.mem]) is of reference type, [[does not apply]]
  • any non-variant non-static data member of const-qualified type ... [[does not apply]]
  • X is a union and ... [[does not apply]]
  • X is a non-union class and all members of any anonymous union member ... [[does not apply]]
  • [applies if the base is a potentially constructed subobject] any potentially constructed subobject, except for a non-static data member with a brace-or-equal-initializer, has class type M (or array thereof) and either M has no default constructor or overload resolution ([over.match]) as applied to find M's corresponding constructor results in an ambiguity or in a function that is deleted or inaccessible from the defaulted default constructor, or
  • any potentially constructed subobject has a type with a destructor that is deleted or inaccessible from the defaulted default constructor. [[does not apply]]

Only one rule potentially applies for the defaulted default constructor being deleted, and it depends on whether the base is a potentially constructed subobject.

[special]

For a class, its non-static data members, its non-virtual direct base classes, and, if the class is not abstract ([class.abstract]), its virtual base classes are called its potentially constructed subobjects.

Derived is abstract (because it doesn't implement all pure virtual functions), and Base is a virtual base, therefore the base is not a potentially constructed subobject, and therefore the only rule that would otherwise have applied for the defaulted constructor being deleted does not apply and thus it should not be deleted. The compiler is wrong.


A simple workaround (besides those that you already mentioned) is to no declare Derived::Derieved() at all. It seems to be correctly implicitly generated in that case.


Adding the noexcept yields the error internal compiler error

This is also a compiler bug.