GCC报'missing initializer for member <anonymous>'警告原因咨询
GCC触发"missing initializer for member 'SpecificData::'"错误的原因分析
问题场景
以下代码在GCC trunk版本下,使用编译选项-std=c++20 -Wall -Wextra -Wpedantic -Werror -O2编译时触发错误:
#include <memory> enum class Type { SpecificType }; struct BaseData { using Ptr = std::unique_ptr<BaseData>; BaseData(Type type) noexcept : type(type) {} const Type type; }; template <typename T, Type VType> struct Data : BaseData { using Ptr = std::unique_ptr<T>; Data() noexcept : BaseData(VType) {} static Ptr make(T&& val) { return std::make_unique<T>(std::move(val)); } }; struct SpecificData : Data<SpecificData, Type::SpecificType> { int field1; int field2; }; int main() { SpecificData::Ptr data = SpecificData::make({ .field1 = 13, .field2 = 42 }); return 0; }
错误信息如下:
<source>:35:48: error: missing initializer for member 'SpecificData::<anonymous>' [-Werror=missing-field-initializers] 35 | SpecificData::Ptr data = SpecificData::make({ .field1 = 13, .field2 = 42 });
但相同编译选项下,Clang和MSVC均可正常编译通过。
原因分析
这个错误是GCC的-Wmissing-field-initializers警告被-Werror转为错误后的结果,本质是GCC对非聚合类指定初始化器的误判:
SpecificData并非聚合类:它继承的基类Data有用户显式声明的构造函数,不符合C++标准中聚合类的定义。- 当使用
{ .field1 = 13, .field2 = 42 }这种指定初始化器创建SpecificData临时对象时,GCC错误地将基类BaseData中的const Type type成员判定为SpecificData未显式初始化的"匿名成员"。但实际上,SpecificData的构造流程会自动调用基类Data的默认构造函数,而该构造函数已经通过BaseData(VType)完成了type成员的初始化。 - Clang和MSVC正确识别了基类成员已被构造函数初始化的事实,因此不会触发该警告。这属于不同编译器对警告规则的实现差异,并非代码本身存在未初始化的问题。
可选解决方案
- 若不想修改代码,可添加编译选项
-Wno-missing-field-initializers关闭该特定警告。 - 也可以调整
make函数的调用方式,避免使用指定初始化器,例如给SpecificData添加构造函数后,改用:SpecificData::make(SpecificData(13, 42))。
内容的提问来源于stack exchange,提问作者Petok Lorand
相关产品推荐
相关产品推荐

