c ++数组零初始化:这是一个bug,还是这是正确的? [英] c++ array zero-initialization: Is this a bug, or is this correct?
问题描述
注意:我们在这里谈论(推测)C ++ 98兼容的编译器。这不是C ++ 11的问题。
我们在一个编译器中有一个奇怪的行为,我们不知道这是否OK如果这是一个编译器错误:
//这个结构有一个默认的构造函数
struct AAA
{
AAA():value(0){}
int value;
};
//这个结构体有一个类型为AAA的数组和一个int数组,两个都包围
//由ints
struct BBB
{
int嘛 ;
AAA m_b;
int m_c;
int m_d [42];
};
当BBB初始化时:
BBB bbb = {0};
我们预计BBB的所有POD成员(包括m_d,int数组)
这在Linux / GCC-3.4的Windows / VisualC ++上的AIX本机编译器上工作。 ...但不是在Solaris / SunStudio上,其中只有非数组成员是零初始化的。
我们做了一点研究,在C ++ 98标准(文件草稿),其中我们发现了以下内容:
[12.6.1 - 2]
当聚合(无论是类还是数组)包含类类型的成员,并且由括号括起来的初始化列表(8.5.1)初始化时,每个这样的成员被复制初始化相应的赋值表达式。 如果初始化器列表中的初始化器比聚合器中的初始化器更少,那么每个未明确初始化的成员都将被默认初始化(8.5)。
然后:
对于类型为T的对象,b
对零初始化存储意味着:
- 如果T是标量类型将值0(零)转换为T;
- 如果T是非联合类类型,则每个非静态数据成员和每个基类子对象的存储为零 - 初始化;
- 如果T是联合类型,其第一个数据成员的存储器89)是零初始化;
- 如果T是数组类型,每个元素的存储均为零初始化;
- 如果T是引用类型,则不执行初始化。
然后:
To default-initialize 一个类型为T的对象意味着:
- 如果T是一个非POD类类型(第9节),T的默认构造函数被称为(如果T没有可访问的默认构造函数,则初始化是错误的);
- 如果T是数组类型,每个元素都是默认初始化的; >
- 否则,对象的存储为零初始化。
我读的方式:SunStudio应该零初始化int数组(BBB :: m_d)
奇怪的事情:如果我们从AAA删除默认构造函数,那么BBB中的所有内容都是零初始化的。
问题:当SunStudio无法初始化一个包含非-荚?或者这是一个编译器错误?
这确实是Sun / Solaris的错误。
你写的东西确实是应该发生的,你对你写的一切都是正确的。
Note: We are speaking about (supposedly) C++98 compliant compilers, here. This is not a C++11 question.
We have a strange behavior in one of our compilers and we're not sure if this is Ok or if this is a compiler bug:
// 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] ;
} ;
When BBB is initialized as such:
BBB bbb = {0} ;
We expected all the POD members of BBB (including m_d, the array of ints) to be zero-initialized, and all the non-POD members of BBB to be constructed.
This worked on the native compiler of AIX, on Linux/GCC-3.4, on Windows/VisualC++... But not on Solaris/SunStudio, where only the non-arrays members are zero-initialized.
We did a little research, in the C++98 standard (a draft document), where we found the following:
[12.6.1 - 2]
When an aggregate (whether class or array) contains members of class type and is initialized by a brace-enclosed initializer-list (8.5.1), each such member is copy-initialized (see 8.5) by the corresponding assignment-expression. If there are fewer initializers in the initializer-list than members of the aggregate, each member not explicitly initialized shall be default-initialized (8.5).
Then:
[8.5 - 5]
To zero-initialize storage for an object of type T means:
— if T is a scalar type (3.9), the storage is set to the value of 0 (zero) converted to T ;
— if T is a non-union class type, the storage for each nonstatic data member and each base-class subobject is zero-initialized;
— if T is a union type, the storage for its first data member 89) is zero-initialized;
— if T is an array type, the storage for each element is zero-initialized;
— if T is a reference type, no initialization is performed.
And then:
To default-initialize an object of type T means:
— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, the storage for the object is zero-initialized.
The way I read it: SunStudio should zero-initialize the array of ints (BBB::m_d)
Strange thing: if we remove the default constructor from AAA, then everything in BBB is zero-initialized.
QUESTION: Is SunStudio behavior standard when it fails to zero-initialize an array of ints of a struct containing a non-POD? Or is this a compiler bug?
It is indeed a bug with Sun/Solaris. What you've written is indeed what is supposed to happen and you are correct with everything you write.
这篇关于c ++数组零初始化:这是一个bug,还是这是正确的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!