【问题标题】:c++ array zero-initialization: Is this a bug, or is this correct?c ++数组零初始化:这是一个错误,还是正确的?
【发布时间】: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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    这显然是 Sun CC 中的一个错误。标准是明确的,你对它的理解是正确的。

    【讨论】:

      【解决方案3】:

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

      我建议通过更明确的方式解决该问题:

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

      【讨论】:

        猜你喜欢
        • 2014-12-29
        • 2021-12-19
        • 1970-01-01
        • 1970-01-01
        • 2016-12-17
        • 2023-03-09
        • 1970-01-01
        • 2018-01-12
        • 1970-01-01
        相关资源
        最近更新 更多