11

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 Answers1

6

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

bames53
  • 86,085
  • 15
  • 179
  • 244
  • Yes, it's indeed a gcc's bug. – Marco A. Sep 27 '14 at 19:28
  • 1
    That bug refers to [DR 253](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#253), which suggests that GCC's behaviour is the intended behaviour, and the standard will be updated to require exactly that. –  Sep 27 '14 at 19:30
  • @hvd Ah, thanks. I saw the mention of DR 253 but never did track it down. Updating my answer. – bames53 Sep 27 '14 at 19:43
  • @MarcGlisse hmmm, you're right. I guess I was seeing that flag come from some other place. – bames53 Sep 27 '14 at 23:55
  • I'd say it's rather dodgy to implement an issue that's not even "ready" (and doesn't even have a proposed resolution), let alone a "DR". I'd call this non-conforming. – Kerrek SB Dec 20 '14 at 23:30