Why does gcc allow a const object without a user-d

2019-01-18 23:40发布

问题:

Recently Why does a const object requires a user-provided default constructor? was marked a duplicate of Why does C++ require a user-provided default constructor to default-construct a const object?. I'm using coliru and rextexter to test out the various versions of gcc (g++-4.7, g++-4.8, g++-4.9) and clang (3.4 and 3.5) to see whether or not this behavior was introduced in newer versions of the compiler. Here we have two test cases, pulled from both questions respectively:

class A {
public:
    void f() {}

};

int main()
{
    A a;       // OK
    const A b; // ERROR

    a.f();
    return 0;
}

and:

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;
}

clang errors out with:

 error: default initialization of an object of const type 'const A' requires a user-provided default constructor
  A const a;
          ^

expectedly but not gcc and neither does MSVC. I thought perhaps I might be going crazy because the standard quotes clearly say:

§ 8.5

6 To default-initialize an object of type T means:

— if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

[...]

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.

11 If no initializer is specified for an object, the object is default-initialized; [...]

The non-POD language present in the second question seems to be missing from n3337 so perhaps I'm missing something that might've changed. Is this a bug, duplicate or am I missing something?

回答1:

The spec currently requires user-provided default constructors but it appears that GCC is implementing a change based on DR 253 which says that if all sub-objects would be initialized without a user provided default constructor then a user-provided default constructor is not required.

This change is only draft status, has not been accepted yet and is not part of the standard. So I think think this is behavior intended by GCC developers but I'm not sure if this is a conforming extension though.

Here's a change to the first example which causes GCC to produce an error:

class A {
public:
    void f() {}

    int i;
};

int main()
{
    A a;       // OK
    const A b; // ERROR

    a.f();
    return 0;
}

Note that gcc downgrades the error to a warning with the -fpermissive flag.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42844



标签: c++ gcc clang