c ++数组零初始化:这是一个错误,还是这个正确?

时间:2013-08-19 07:58:22

标签: c++ standards-compliance c++98 compiler-bug

注意:我们在这里谈论(据称)与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的结构的整数数组进行零初始化?或者这是编译器错误?

3 个答案:

答案 0 :(得分:2)

这确实是Sun / Solaris的一个错误。 你所写的确实是应该发生的事情,你对所写的一切都是正确的。

答案 1 :(得分:1)

这显然是Sun CC中的错误。标准很清楚,你对它的理解是正确的。

答案 2 :(得分:1)

这似乎是一个错误 - 我没有Solaris编译器的经验,但我使用的所有其他编译器都允许这种初始化。

我建议通过更明确地解决问题:

 BBB bbb = {0, 0, 0, {0} };