注意:我们在这里谈论(据称)与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,整数数组)被零初始化,并且要构建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的结构的整数数组进行零初始化?或者这是编译器错误?
答案 0 :(得分:2)
这确实是Sun / Solaris的一个错误。 你所写的确实是应该发生的事情,你对所写的一切都是正确的。
答案 1 :(得分:1)
这显然是Sun CC中的错误。标准很清楚,你对它的理解是正确的。
答案 2 :(得分:1)
这似乎是一个错误 - 我没有Solaris编译器的经验,但我使用的所有其他编译器都允许这种初始化。
我建议通过更明确地解决问题:
BBB bbb = {0, 0, 0, {0} };