在下面的例子中,用括号初始化Vec3
是否保证所有x
,y
和z
都默认初始化(func_a()
),与func_b()
不同,其中所有成员都获得未定义的值?
struct Vec2 { float x, y; };
struct Vec3 { Vec2 xy; float z; };
auto func_a() {
Vec3 v{};
return v;
}
auto func_b() {
Vec3 v;
return v;
}
如果是这样,是否有任何例外,即使它所属的类被使用大括号初始化,成员也不会被初始化?
Clang和GCC为func_b()
产生不同的组装。
在Clang中,汇编是单一的ret
声明。
在GCC中,程序集类似于func_a():
mov DWORD PTR [rsp-24], 0x00000000
mov DWORD PTR [rsp-20], 0x00000000
pxor xmm1, xmm1
movq xmm0, QWORD PTR [rsp-24]
ret
(编译器资源管理器链接https://godbolt.org/z/XqwgSV)
什么对应于你的reference的例子
T object {}; // (4) (since C++11)
在以下情况下执行值初始化: ... 4)当声明一个命名变量(自动,静态或线程局部)时,初始化器由一对大括号组成。
值初始化的效果是: ... 2)如果T是具有默认构造函数的类类型,该构造函数既不是用户提供也不是删除(也就是说,它可能是具有隐式定义或默认默认构造函数的类),该对象是零初始化的,然后它是default-initialized如果它有一个非平凡的默认构造函数;
所以在你的情况下,zero initialization将会发生。
如果T是非联合类类型,则所有基类和非静态数据成员都是零初始化的,并且所有填充都初始化为零位。构造函数(如果有)将被忽略。