g++11 :摆脱成员 'A::<anonymous>' 缺少的初始值设定项

g++11 : getting rid of missing initializer for member 'A::<anonymous>'

我即将发布一个代码,我不希望其中有任何警告。 目前 运行 -Wall -Wextra 尽我所能。

现在我有了这个示例代码(从生产代码中非常人为地设计):

// 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;
}

可以在这里测试: Godbolt test case

然后我得到: 警告:缺少成员 'A::' [-Wmissing-field-initializers]

的初始值设定项

现在,真正的问题是 真正 缺乏初始化会产生很多后果(想想现实生活中的伤害)。

请注意,所有字段都有默认初始化。并且单元测试显示字段已正确初始化(运气?)

同样,我对这个警告感到非常不舒服。

需求:

在生产代码中,结构足够大,我不愿意用这种表示法手动初始化所​​有成员(并且使用许多初始化策略,它很快变得 unbearable/error 容易)

如何在不关闭 -Wextra 的情况下设法使此警告消失(同样,认为在缺少初始化的情况下会造成损坏)?

更新:

我看到了其他相关问题,但考虑到风险,我真的很想深入了解这个特殊案例。

更新 2:

阅读不同编译器的程序集,他们似乎采取了正确的行动,但只有 GCC 抱怨。

对于问题:“我的字段都初始化了吗?”

开始

all the fields have a default initialization

答案是:

来源:https://en.cppreference.com/w/cpp/language/aggregate_initialization

部分:指定的初始值设定项 示例:

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

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

现在,如何处理警告。我能想到的:

  1. 将所有初始化 => 代码添加到 big
  2. Disable locally the warning => 同样的问题
  3. 不要使用-Wall -Wextra而是使用减号内的所有警告 -Wmissing-field-initializers 并在您的测试中添加带有 clang 完整警告和 -Werror.
  4. 的构建

如果你的代码库不能用 clang 编译,我能想到的最后一件事是:做一个列出所有“不需要的警告”的脚本和 运行 你的构建,如果你有一个新的警告: 修理它。它很丑,而且扩展性不好。