5

I'm learning c++ and I've encountered the following strange thing:

If I initialize array like the book says

int my_array[5] = {10}

every array field is still initialized to zero, when it should be ten.

If I initialize it in a loop, it works as intended

What is happening? I'm using Ubuntu and compiling with g++

Marko Kacanski
  • 423
  • 9
  • 17

3 Answers3

11

What you observe is correct: the remaining items of the array are initialized to 0, according to the standard.

Jarhmander
  • 344
  • 5
  • 19
  • Yes, I see that it is correct behaviour. The tutorial I'm using said that by using array[5] = {0} you init everything to zero. I wrongly assumed it would work with all values. – Marko Kacanski Dec 13 '13 at 21:25
  • 2
    @MarkoKacanski That method is optimal for value 0, as the compiler may assign all values 0 in any order, and essentially optimize itself. To do the same in an incremental for-loop is much less optimal, as you specify the iterator, order, and value for all elements. However, that's the only way (that I know of) to initialize to non-zero values. (`std::fill_n` internally works the same) – Trojan Dec 13 '13 at 21:27
  • 1
    using `= {0}` is the same as using `= {}` and letting the compiler implicitly zero-initialize the first element for you. In other words, when using braces, any value you explicitly specify will initialize only that field to that specific value and then any unspecified fields will be zero-initialized instead. So if you omit the first field, the compiler will simply zero-initialize it for you. – Remy Lebeau Dec 13 '13 at 21:31
  • 2
    Marko, what your book said was true, although if that's all it said on the matter, it was misleading. The reason the first element was initialized to zero was not the same as the reason the remaining elements were initialized to zero. Your book should have mentioned that distinction, perhaps by using an example like the one you cite in your question. I once assumed the same as you did. – Rob Kennedy Dec 13 '13 at 21:53
7

The C++03 (assuming if you have an older version of GCC on an Ubuntu system) standard says:

8.5.1/7

If there are fewer initializers in the list than there are members in the aggregate, then each member not explicitly initialized shall be value-initialized (8.5).

And an array is an aggregate:

8.5.1/1

An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).

As to what value-initialized means:

To value-initialize an object of type T means:

— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

... and skipping everything an int is not ...

— otherwise, the object is zero-initialized

Which is what happens for a variable of type int.

  • That was exactly the kind of supporting information I wanted to post. Do you have a copy of the standard or you look at some online resource? – Jarhmander Dec 13 '13 at 21:39
6

When initialized with a list smaller than the array, only the specified elements are initialized as you expected; the rest are initialized to 0.

To initialize all values, use a loop, or std::fill_n, as shown here.

std::fill_n(my_array, 5, 10); // array name, size, value

Internally, std::fill_n is equivalent to a loop. From the first link:

template <class OutputIterator, class Size, class T>
    OutputIterator fill_n (OutputIterator first, Size n, const T& val)
{
    while (n>0) {
        *first = val;
        ++first; --n;
    }
    return first;     // since C++11
}
Community
  • 1
  • 1
Trojan
  • 2,256
  • 28
  • 40