Why does C++ require a user-provided default constructor to default-construct a const object?

c++

Solution

This was considered a defect (against all versions of the standard) and it was resolved by Core Working Group (CWG) Defect 253. The new wording for the standard states in http://eel.is/c++draft/dcl.init#7

A class type T is const-default-constructible if default-initialization of T would invoke a user-provided constructor of T (not inherited from a base class) or if

- each direct non-variant non-static data member M of T has a default member initializer or, if M is of class type X (or array thereof), X is const-default-constructible,

- if T is a union with at least one non-static data member, exactly one variant member has a default member initializer,

- if T is not a union, for each anonymous union member with at least one non-static data member (if any), exactly one non-static data member has a default member initializer, and

- each potentially constructed base class of T is const-default-constructible.

If a program calls for the default-initialization of an object of a const-qualified type T, T shall be a const-default-constructible class type or array thereof.

This wording essentially means that the obvious code works. If you initialize all of your bases and members, you can say `A const a;` regardless of how or if you spell any constructors.

struct A {
};
A const a;

gcc has accepted this since 4.6.4. clang has accepted this since 3.9.0. Visual Studio also accepts this (at least in 2017, not sure if sooner).

Problem

The C++ standard (section 8.5) says: If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor. Why? I can't think of any reason why a user-provided constructor is required in this case. ``` struct B{ B():x(42){} int doSomeStuff() const{return x;} int x; }; struct A{ A(){}//other than "because the standard says so", why is this line required? B b;//not required for this example, just to illustrate //how this situation isn't totally useless }; int main(){ const A a; } ```

Original source