6

Consider the code:

struct Foo
{
    int x = 10;
};

int main()
{
    const Foo foo;
}

It compiles under g++ http://coliru.stacked-crooked.com/a/99bd8006e10b47ef, however spits an error under clang++ http://coliru.stacked-crooked.com/a/93f94f7d9625b579 :

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

I am not sure who's right here. Why do we need a default ctor since we perform in-class initialization?

greatwolf
  • 20,287
  • 13
  • 71
  • 105
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Here is a great answer. http://stackoverflow.com/questions/7411515/why-does-c-require-a-user-provided-default-constructor-to-default-construct-a – Thellimist Dec 20 '14 at 22:46
  • 2
    This is [CWG issue 253](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#253). – T.C. Dec 20 '14 at 22:46
  • @Furkan, note that I know why the rule is as it is, I don't understand why is it applicable in my case, as my object is perfectly well defined at runtime. – vsoftco Dec 20 '14 at 22:47
  • @T.C.: Are you sure a core issue from 2000 is relevant? – Kerrek SB Dec 20 '14 at 22:57
  • 1
    @KerrekSB: consider the comment from the august 2011 meeting, "If the implicit default constructor initializes all subobjects, no initializer should be required.". that's clearly the *intent* for c++11. it didn't make it into the standard, though. – Cheers and hth. - Alf Dec 20 '14 at 22:59
  • @Cheersandhth.-Alf I don't know what exactly "implicit default constructor initializes all subobjects" means here. If I do in-class initialization, is it internally transformed into an implicit default ctor that performs it? – vsoftco Dec 20 '14 at 23:01
  • @vsoftco: yes, exactly. – Cheers and hth. - Alf Dec 20 '14 at 23:02

2 Answers2

7

An object of class type may only be default-initialized if it has a user-provided default constructor. From [dcl.init]/7:

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.

Your class Foo doesn't have that; the presence of a brace-or-equals-initializer does not create a user-provided default constructor. Rather, your class has an implicitly defined default constructor, whose action incorporates the initialization as requested by the brace-or-equals-initializer. (Clang is right.)

([dcl.fct.def.default], in particular paragraph 5, relates the definitions of "user-provided", "explicitly defaulted", "implicitly declared" and "defined as deleted". The entire section is worth knowing.)

By the way, it's easy to avoid default-initialization in C++11:

const Foo foo {};  // hunky-dory
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • **+1** for the "hunky dory". :) – Cheers and hth. - Alf Dec 20 '14 at 23:03
  • What difference does `{}` make?? – David G Dec 20 '14 at 23:25
  • @0x499602D2 it value-initializes, so the compiler is happy that in a `const` you have everything initialized. I guess the problem in my case is when you have an additional `y` variable that you don't in-class initialize. Standard C++ decided that it won't bother checking that all members are in-class initialized, so the old rule is still applicable. – vsoftco Dec 20 '14 at 23:41
  • @vsoftco: In C++14, I think it would be aggregate-initialization. The rules have changed a little bit to allow aggregates to have BOEIs. – Kerrek SB Dec 20 '14 at 23:45
  • @KerrekSB what is BOEIs? Sorry for my ignorance :) – vsoftco Dec 20 '14 at 23:45
  • @vsoftco: *brace-or-equals-initializer*. I got tired of typing that :-) – Kerrek SB Dec 20 '14 at 23:46
  • @KerrekSB ha ha, ok, will remember. And just tested that g++ (4.9.2) doesn't yet allow BOEI for aggregates with `-std=c++14`, but clang++ does. – vsoftco Dec 20 '14 at 23:46
3

clang seems to be right according to 8.5 [dcl.init] paragraph 7 last sentence:

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.

Clearly, the type doesn't have a user-provided default constructor.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380