C++初始化期间引用结构体成员是否合法?
问题解答
这种情况是合法的,不会触发未定义行为,具体分析如下:
核心规则依据
你的代码中Foo属于C的聚合类型(满足无用户定义构造函数、无基类、无虚函数等聚合判定条件),因此使用的是聚合初始化逻辑。根据C标准,聚合初始化时,成员的初始化顺序严格遵循结构体中成员声明的先后顺序,和初始化列表里的指定顺序无关。
针对你的代码分析
看Foo的成员声明:
struct Foo { Data data; Bar b; };
data的声明在b之前,所以初始化流程是:
- 先完成
f.data的初始化(通过Data()进行值初始化,Data的成员b会被默认初始化为0); - 再初始化
f.b,此时f.data已经是完全构造完成的对象,用它来构造Bar完全合法,不存在未定义行为。
反例(触发未定义行为的情况)
如果把Foo的成员顺序调换:
struct Foo { Bar b; Data data; };
此时聚合初始化会先构造b,而data还未完成初始化,这时候访问f.data就会触发未定义行为。
你的代码示例:
struct Data { int b; }; struct Bar { Bar(Data& d): a(d.b){ } int a; }; struct Foo { Data data; Bar b; }; int main() { Foo f {.data = Data(), .b = Bar(f.data)}; // b is constructed using f.data! }
内容的提问来源于stack exchange,提问作者user3001150
相关产品推荐
相关产品推荐

