嵌套结构编译器错误的零初始化
Zero initialization of nested struct - compiler bug?
考虑这个例子:
#include <vector>
#include <stdexcept>
struct A
{
float a;
float b;
float c;
float d;
};
struct B
{
A a;
std::vector<int> b;
};
int main() {
B b{};
if (b.a.a || b.a.b || b.a.c || b.a.d) throw std::runtime_error("Compiler bug?");
}
如果我理解正确,根据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似乎认为使用大括号必须执行零初始化。
编辑:我在英特尔的网站上提交了一个错误:https://community.intel.com/t5/Intel-C-Compiler/Aggregate-initialization-bug-with-nested-struct/td-p/1178228
一位情报人员回答说:;我已经向我们的开发人员报告了这个问题"糟糕的开发人员,独自支持所有icc的开发。
首先:保证对象b.a.a
、b.a.b
、b.a.c
、b.a.d
初始化为零。其对于CCD_ 5被初始化为好像通过CCD_。
B b{};
仅在某些情况下转换为零初始化(cpprreference页面有点误导(。
在C++14中:由于B
是一个聚合,所以这是聚合初始化,每个成员都被初始化为空列表。所以A a;
被初始化为A a{};
。A
也是一个聚合,因此它的每个元素都被初始化为一个空列表,对于内置类型来说,这是零初始化。
在C++11中,措辞不同(从空列表对聚合类进行列表初始化实际上并不被视为聚合初始化(,但结果是相同的。
在C++03中,B b{}
;是一个语法错误,但B b = {};
是允许的,并且对有问题的浮点值也进行了零初始化。
在C++98中,规则是不同的,长话短说,B b = {};
将调用A
的默认构造函数,这将使值未初始化。我们喜欢假装C++98初始化从未存在过,但一些编译器甚至在2010年代都坚持这些规则。
如果不这样做,可能会有一些关于零初始化浮点是否保证充当||
运算符的false
的争论,请参阅将浮点数与零进行比较。
该标准规定"零值、空指针值或空成员指针值转换为false
"。这不是100%精确的,但为了这个目的,初始化为零的float
应该算作"零值"。
- 使用默认构造函数引用成员变量初始化错误
- 交换机案例语句中的初始化错误
- 英特尔 MKL 稀疏 QR 求解 C++ 返回未初始化错误
- 在模板类中使用"this"会导致参数初始化错误
- 映射的映射集的映射初始化错误
- C++图形初始化错误(语法或丢失文件缺陷?
- QSQLDATABASE:SIGSEV初始化错误
- 映射的 std::for_each() 给出无效的初始化错误
- 初始化错误过多
- C++初始化错误 std::set
- 简单的类构造函数初始化错误
- 组合框初始化错误:无法读取未定义的属性'constructor'
- OpenCV卡尔曼滤波器初始化错误
- C++11动态数组部分列表初始化(错误或误解)
- C++ 静态变量在发布模式下初始化错误
- Visual Studio 2010 SP1 中的 64 位整数初始化错误
- C++libPNG-简单初始化错误
- 结构数组-初始化错误
- 初始化错误
- 我不断收到函数初始化错误.(运行时检查失败 #3)