注意:我们在这里谈论(据说)符合 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 的结构的整数数组进行零初始化时,它的行为标准吗?或者这是一个编译器错误?