为何C++编译器对全局初始化的C结构体报未初始化字段警告?
关于extern "C"结构体全局初始化的编译器警告疑问
代码示例
extern "C" { struct Foo { int field1; int field2; }; } Foo foo = {0};
编译器警告
warning: missing field 'field2' initializer [-Wmissing-field-initializers]
疑问点
- 该结构体是extern "C"结构体,不存在构造函数;
- 编译器未对field1发出警告,这似乎暗示存在聚合或直接初始化操作,但与第1点存在矛盾;
- field1和field2显然都已完成初始化。
为何编译器仅针对field2发出警告,却不针对field1?
解答
extern "C"不改变结构体的聚合类型本质:extern "C"仅修改结构体的链接属性与名称修饰规则,不会改变它在C++中作为聚合类型的属性。聚合类型天然支持聚合初始化,不需要依赖构造函数,这和"不存在构造函数"的前提完全不矛盾。
初始化规则与警告逻辑:用
{0}初始化聚合类型时,第一个显式值会赋值给field1,剩余未被显式指定的成员(即field2)会被自动值初始化为0。但-Wmissing-field-initializers警告的触发逻辑很直接:只要初始化列表提供的元素数量少于结构体成员总数,就会对未被显式覆盖的成员发出警告——它只检查你有没有在初始化列表里写出对应成员的初始化值,不关心这些成员是否会被自动初始化。规避警告的写法:如果想让所有成员都被值初始化且消除警告,可以写成
Foo foo = {};,空初始化列表会触发聚合类型的全成员值初始化,编译器不会再提示遗漏初始化的问题。
内容的提问来源于stack exchange,提问作者Spongman
相关产品推荐
相关产品推荐

