3

I am about to release a code and I want no warnings in it. Currently running with -Wall -Wextra to hunt down everything I can.

Now I have this example code (extremely contrived from the production code):

// Type your code here, or load an example.
#include <iostream>
#include <vector>
using namespace std;

struct A {
  union {
    int i = 82, j;
  };
  int a = 98, b = 22;
};

int main() {
  A p = {.a = 45};

  cout << p.a << endl; // just here to prevent optimization
  cout << p.i << endl; // same

  return 0;
}

That can be tested here : Godbolt test case

And I get: warning: missing initializer for member 'A::' [-Wmissing-field-initializers]

Now, the real issue is that a real lack of initialization can have a lot of consequences (think real life damage).

Please note that all the fields have a default initialization. And the unit tests show that fields are properly initialized (luck?)

Again, I am VERY uncomfortable with this warning.

The need:

In production code, the struct is big enough for me not willing to manually initialize all the members with this notation (and with many initialization strategies it becomes unbearable/error prone very quickly)

How can I manage to make this warning disappear (again, think damage in case of a lack of initialization), without just turning off -Wextra?

Update:

I saw other related questions, but given the risks I really want to have an insight on this particular case.

Update 2:

Reading the assembly for different compilers, they seem to take the proper course of action, but only GCC complains.

Kroma
  • 1,109
  • 9
  • 18

1 Answers1

1

For the question : "Are all my field initialized ?"

Since

all the fields have a default initialization

The answer is: yes

Source: https://en.cppreference.com/w/cpp/language/aggregate_initialization

Section: Designated initializers Example:

struct A { int x; int y; int z; };
A a{.y = 2, .x = 1}; // error; designator order does not match declaration order
A b{.x = 1, .z = 2}; // ok, b.y initialized to 0

and

struct A {
  string str;
  int n = 42;
  int m = -1;
};
A{.m=21}  // Initializes str with {}, which calls the default constructor
          // then initializes n with = 42
          // then initializes m with = 21

Now, how deal with warning. All I can think of:

  1. Add all initialization => code to big
  2. Disable locally the warning => same problem
  3. Don't use -Wall -Wextra but use all the warning inside minus -Wmissing-field-initializers and add in your test a build with clang full warning and -Werror.

If your code base can't compile with clang, the last thing I can think of is: do a script that list all "unwanted warning" and run your build, if you have a new warning : fix it. It's ugly and does not scale well.

Martin Morterol
  • 2,560
  • 1
  • 10
  • 15
  • 2
    Thanks Martin, I will keep checking the assembly and rely on the fact that initialization should occur. I should fill a gcc bug report as well but I know they are already aware of the issue. – Kroma Jul 31 '21 at 09:20