Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ array zero-initialization: Is this a bug, or is this correct?

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?

like image 598
paercebal Avatar asked Aug 19 '13 07:08

paercebal


People also ask

Are arrays 0 initialized in C?

An array may be partially initialized, by providing fewer data items than the size of the array. The remaining array elements will be automatically initialized to zero.

Can array be initialize to zero?

The array will be initialized to 0 in case we provide empty initializer list or just specify 0 in the initializer list. Designated Initializer: This initializer is used when we want to initialize a range with the same value.

Why do we initialize array with 0?

Initialization to zeros is needed because each element in the array is a counter. If you add 1 (or do other math) to something that is NaN (not a number) or undefined, then you'll either get an error or unreliable results.

Do you need to initialize an array in C?

We don't need to initialize all the elements 0 to 4. We can even do only from indices 0 to 2. But now, arr[4] and arr[5] will still remain garbage values, so you need to be careful! If you're using an initializer list with all elements, you don't need to mention the size of the array.


2 Answers

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.

like image 103
Yonatan Nir Avatar answered Sep 28 '22 11:09

Yonatan Nir


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

like image 41
James Kanze Avatar answered Sep 28 '22 11:09

James Kanze