在下面的示例中,是否使用花括号初始化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)
答案 0 :(得分:1)
T object {}; // (4) (since C++11)
在以下情况下执行值初始化:
...
4)当使用由一对大括号组成的初始化器声明命名变量(自动,静态或线程局部)时。值初始化的影响是:
...
2)如果T是具有既不由用户提供也未删除的默认构造函数的类类型(即,它可能是具有隐式定义或默认默认构造函数的类),则该对象为零初始化< / strong>,如果具有非平凡的默认构造函数,则将其默认初始化;
因此,在您的情况下,将发生zero initialization。
如果T是非联合类类型,则所有基类和非静态数据成员都将初始化为零,并且所有填充都将初始化为零位。构造函数(如果有)将被忽略。