4

I have an aggregate structure B derived from another aggregate A. I would like to initialize it and there are two options: ordinary aggregate initialization and C++20 designated initializers:

struct A {};
struct B : A { int x; };

int main() {
    [[maybe_unused]] B x{{},1}; //ok everywhere
    [[maybe_unused]] B y{.x=1}; //warning in GCC
}

The ordinary initialization {{},1} works fine, but it looks too clumsy in this case due to extra {} for parent aggregate.

And designated initializers {.x=1} look better to me here, but they produce a weird warning in GCC:

warning: missing initializer for member 'B::<anonymous>' [-Wmissing-field-initializers]
    6 |     [[maybe_unused]] B y{.x=1}; //warning in GCC
      |                              ^

Demo: https://gcc.godbolt.org/z/8jEYY16c6

Is there a way to use designated initializers here and calm down GCC at the same time to eliminate the warning?

Fedor
  • 17,146
  • 13
  • 40
  • 131
  • Not see this warning in MSVC for the designated initializer case either (and that's with `/W4` and a host of other switches I like to enable... – WBuck Aug 07 '21 at 20:17
  • Looks like a GCC bug https://stackoverflow.com/questions/49081541 That target is for C, but I assume GCC is using the same machinery for C++20 designated initializers, and hence the warning. – cigien Aug 07 '21 at 20:28

2 Answers2

5

Is there a way to use designated initializers here and calm down GCC at the same time to eliminate the warning?

No. GCC's warning is correct: you are missing an initializer for the base class, A. Now, in this case you happen to want to initialize from = {} anyway (which is what happens when you don't provide an initializer) and that's the only thing you can initialize it from, so maybe in this specific case it's a bit silly to warn (but in the general case where the base class actually has members, it is totally reasonable). Also the warning could be more useful and actually tell you which member you're missing an initializer for...

Unfortunately, there is no way to actually name the base class in a designated-initializer-list, which means there's no way to actually initialize B using designated initializers.

There is a proposal to fix this (P2287), the intent of which would be to allow B{.A={}, .x=1}, but that's still a work in progress.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • From https://en.cppreference.com/w/cpp/language/aggregate_initialization it seems that the initalizer for `A` can be skipped and it will be aggregate initialized, as if it was initialized with `= {}`. What am I missing? – cigien Aug 07 '21 at 21:39
  • @cigien Yes, that's why it's a warning that an initializer was skipped - not an error. – Barry Aug 07 '21 at 21:48
  • Oh, I see. I read the question as asking if the code is valid, but it seems OP wants to get rid of the warning if it is. – cigien Aug 07 '21 at 21:52
1

Your code is valid, and the warning is correct; you are missing an initializer, which will be aggregate initialized.

You can disable the warning with the flag -Wno-missing-field-initializers.

demo

cigien
  • 57,834
  • 11
  • 73
  • 112