嵌套结构的零初始化-编译器错误?

时间:2020-05-05 00:24:53

标签: c++ c++14

考虑以下示例:

Load Balancer

根据https://en.cppreference.com/w/cpp/language/zero_initialization,如果我理解正确,它就不会抛出异常,因为应该对B :: a进行零初始化,就像对“没有构造函数的值初始化类类型的成员”一样。 >

如果抛出,是编译器错误还是我缺少什么?

[编辑]

在这里启用了clang 10并启用了优化,它只执行“ mov eax,2”和“ ret”(表示条件为假): https://godbolt.org/z/CXrc3G

但是,如果我移除括号,它将执行“ mov eax,1”和“ ret”操作(这意味着条件是正确的)。但是在这里,我认为它可以返回任何所需内容,因为它只是UB。 https://godbolt.org/z/tBvLzZ

因此,似乎clang认为使用花括号时必须执行零初始化。

1 个答案:

答案 0 :(得分:5)

首先:确保对象b.a.ab.a.bb.a.cb.a.d被零初始化。 float的哪个被初始化为好像由= 0;初始化(不一定表示所有位为零)。

B b{};仅在某些情况下转换为零初始化(cppreference页有点误导)。

在C ++ 14中:由于Baggregate,因此这是聚合初始化,每个成员的初始化就好像是一个空列表一样。因此A a;就像A a{};一样被初始化。 A也是一个聚合,因此它的每个元素都像一个空列表一样被初始化,对于内置类型,该列表为零初始化。

在C ++ 11中,措辞是不同的(从空列表中初始化聚合类的列表初始化实际上并不认为是聚合初始化),但是结果是相同的。

在C ++ 03中,B b{};是一个语法错误,但允许B b = {};,并且结果是将所涉及的浮点数零初始化。

在C ++ 98中,规则有所不同,总而言之,B b = {};会调用A的默认构造函数,而该构造函数会保留未初始化的值。我们想假装C ++ 98初始化不存在,但是有些编译器甚至在2010年代也坚持使用这些规则。


这样一来,对于false运算符是否可以保证零初始化浮点是否可以充当||有一些争论,请参阅Comparing floating point number to zero

标准说“将零值,空指针值或空成员指针值转换为false”。这不是100%精确的,但为此目的,IMO零初始化的float应该算作“零值”。