Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I be worried about Wmissing-field-initializers and aggregate initialization in C++17?

I compiled some code with GCC with -Wall and -Wextra enabled. This code produces a warning:

struct A { A(int) {} };
struct B {};

struct C : A, B {};

int main() {
    (void) C{1};
}
main.cpp: In function 'int main()':
main.cpp:11:15: warning: missing initializer for member 'C::<anonymous>' [-Wmissing-field-initializers]
     (void) C{1};
               ^

Should I be worried about that? Is this a bug in GCC for outputting this warning? It seems I have no field to initialize, and no missing parameters.

like image 735
Guillaume Racicot Avatar asked Dec 10 '17 05:12

Guillaume Racicot


People also ask

What is aggregate initialization?

Explanation. Aggregate initialization is a form of list-initialization, which initializes aggregates. An aggregate is an object of the type that is one of the following. array type. class type (typically, struct or union), that has.

What is brace initialization?

If a type has a default constructor, either implicitly or explicitly declared, you can use brace initialization with empty braces to invoke it. For example, the following class may be initialized by using both empty and non-empty brace initialization: C++ Copy.

What is aggregate type C++?

An aggregate type is a structure, union, or array type. If an aggregate type contains members of aggregate types, the initialization rules apply recursively.


1 Answers

C++17 allows you to perform aggregate initialization on classes with base classes. Each base class is effectively considered a member (they come before the direct members of the class). So to aggregate initialization, C has two "members": C::A and C::B.

You only initialized one.

Oh sure, B doesn't actually have anything to initialize. But to -Wall, it's no different from this:

struct C
{
  A a;
  B b;
};

(void) C{1};

This would give a warning too. You would silence it in either case by providing an explicit initializer for B: (void)C{1, {}};.

But as far as the standard is concerned, this is perfectly valid code. B will be value initialized. In either case.

like image 64
Nicol Bolas Avatar answered Sep 21 '22 07:09

Nicol Bolas