用大括号初始化类是否可以确保所有成员都默认初始化?

时间:2018-09-04 07:58:01

标签: c++11 initialization undefined list-initialization

在下面的示例中,是否使用花括号初始化Vec3保证了xyz中的所有默认值都已初始化(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

1 个答案:

答案 0 :(得分:1)

reference

中的示例对应的内容
  

T object {}; // (4) (since C++11)

     

在以下情况下执行值初始化:
  ...
  4)当使用由一对大括号组成的初始化器声明命名变量(自动,静态或线程局部)时。

     

值初始化的影响是:
  ...
  2)如果T是具有既不由用户提供也未删除的默认构造函数的类类型(即,它可能是具有隐式定义或默认默认构造函数的类),则该对象为零初始化< / strong>,如果具有非平凡的默认构造函数,则将其默认初始化;

因此,在您的情况下,将发生zero initialization

  

如果T是非联合类类型,则所有基类和非静态数据成员都将初始化为零,并且所有填充都将初始化为零位。构造函数(如果有)将被忽略。