14
votes

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?

3
Seems like a bug to me. What if you write BBB bbb = {0,0,0, {0 } };Mats Petersson
It's an error in Sun CC. Your understanding of the standard is correct.James Kanze
@JamesKanze : I can't really upvote comments, nor choose them as answers... don't hesitate to make a full answer... :-)paercebal
@MatsPetersson : I can't really upvote comments, nor choose them as answers... don't hesitate to make a full answer... :-)paercebal

3 Answers

2
votes

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.

1
votes

This is clearly an error in Sun CC. The standard is clear, and your understanding of it is correct.

1
votes

It seems to be a bug - I have no experience with Solaris compilers, but all other compilers I've worked with will allow this sort of initialization.

I would suggest that work around the problem by being more explicit:

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