Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do clang and gcc handle braced-initialization of structs with in-class initialization differently?

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.

like image 284
user3684240 Avatar asked Dec 28 '15 09:12

user3684240


1 Answers

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 .

like image 56
M.M Avatar answered Nov 09 '22 21:11

M.M