7

I recently discovered an odd behavior of clang and gcc. I have a struct (MyClass) which uses in-class initialization for one of its members (active):

struct MyClass {
  int something;
  bool active = true;
};

Now I try to brace-initialize this class.

Using clang, I can decide whether I include active in the initializer list (MyClass a = { 42, true};) or not (MyClass a = { 42 };).

However using gcc, my code only compiles if I do not include active. Else, I will get the following compiler error:

 error: could not convert ‘{42, true}’ from ‘<brace-enclosed initializer list>’ to ‘MyClass’

Is this a bug? What does the standard say about it? What about VSC++? Which way would you recommend as the portable solution?

Tested using gcc 4.9 and clang 3.5 on Debian Linux.

user3684240
  • 1,420
  • 2
  • 12
  • 18

1 Answers1

9

The behaviour of this code changed between C++11 and C++14.

In C++11 the presence of = true means that the class was not an aggregate. Therefore you could not use aggregate initialization.

In C++14 the class is still an aggregate, so you can use aggregate initialization again.

The difference between compilers could be explained by one being newer than the other. Using compiler explorer I see that gcc 4.9.x gets it wrong , but this is fixed in gcc 5.1 .

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Using clang in c++11 mode supports this hypothesis. It complains about the same things as gcc. – user3684240 Dec 28 '15 at 09:22
  • My guess is that this is technically a bug in C++11 mode in clang - although one that is mostly harmless unless you are specifically looking for an error when this construct is used. – Mats Petersson Dec 28 '15 at 09:38
  • @MatsPetersson it seems correct in clang and bugged in g++ – M.M Dec 28 '15 at 09:43
  • @M.M: Uh, is the code supposed to compile in C++11 mode, then? My comment was to OP's comment that in C++11 mode, it still compiles in clang... – Mats Petersson Dec 28 '15 at 09:48
  • @MatsPetersson I assume he meant that the code fails in clang -std=c++11 and succeeds in clang -std=c++14 , which is the correct behaviour (compiler explorer seems to bear this out) – M.M Dec 28 '15 at 10:09