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?
BBB bbb = {0,0,0, {0 } };
– Mats Petersson