【发布时间】:2013-08-19 07:58:21
【问题描述】:
注意:我们在这里谈论的是(据说)符合 C++98 的编译器。这不是 C++11 问题。
我们的一个编译器有一个奇怪的行为,我们不确定这是否正常或者这是一个编译器错误:
// This struct has a default constructor
struct AAA
{
AAA() : value(0) {}
int value ;
} ;
// This struct has a member of type AAA and an array of int, both surrounded
// by ints
struct BBB
{
int m_a ;
AAA m_b ;
int m_c ;
int m_d[42] ;
} ;
当 BBB 这样初始化时:
BBB bbb = {0} ;
我们期望 BBB 的所有 POD 成员(包括 m_d,int 数组)都被初始化为零,并且 BBB 的所有非 POD 成员都被构造。
这适用于 AIX 的本机编译器、Linux/GCC-3.4、Windows/VisualC++...但不适用于 Solaris/SunStudio,其中只有非数组成员被零初始化。
我们在 C++98 标准(草稿文档)中做了一些研究,发现以下内容:
[12.6.1 - 2]
当聚合(无论是类还是数组)包含类类型的成员并由大括号括起来的初始化器列表(8.5.1)初始化时,每个这样的成员都通过相应的赋值进行复制初始化(参见 8.5)-表达。 如果初始化器列表中的初始化器少于聚合的成员,则每个未显式初始化的成员都应默认初始化(8.5)。
然后:
[8.5 - 5]
对 T 类型的对象进行零初始化存储意味着:
— 如果 T 是标量类型(3.9),则存储设置为转换为 T 的值 0(零);
— 如果 T 是非联合类类型,则每个非静态数据成员和每个基类子对象的存储都是零初始化的;
— 如果 T 是联合类型,则其第一个数据成员 89) 的存储是零初始化的;
— 如果 T 是数组类型,则每个元素的存储都是零初始化的;
— 如果 T 是引用类型,则不执行初始化。
然后:
默认初始化类型 T 的对象意味着:
— 如果 T 是非 POD 类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化是非良构的);
— 如果 T 是数组类型,则每个元素都是默认初始化的;
— 否则,对象的存储将被初始化为零。
我的阅读方式:SunStudio 应该零初始化整数数组 (BBB::m_d)
奇怪的事情:如果我们从 AAA 中删除默认构造函数,那么 BBB 中的所有内容都是零初始化的。
问题:当 SunStudio 未能对包含非 POD 的结构的整数数组进行零初始化时,它的行为是否标准?或者这是一个编译器错误?
【问题讨论】:
-
对我来说似乎是一个错误。如果你写
BBB bbb = {0,0,0, {0 } }; -
这是 Sun CC 中的错误。您对标准的理解是正确的。
-
@JamesKanze :我不能真正支持 cmets,也不能选择它们作为答案...不要犹豫,做出完整的答案... :-)
-
@MatsPetersson :我不能真正支持 cmets,也不能选择它们作为答案......不要犹豫,做出完整的答案...... :-)
标签: c++ standards-compliance c++98 compiler-bug