3

For some reason I had this idea that C and C++ worked like this:

int foo[10] = {57};
for (int i=0; i<10; ++i)
    assert (foo[i] == 57);

Turns out the remaining ints are initialized to 0, not 57. Where did I get this idea? Was this true at one point? Was it ever true for structure initializer lists? When did arrays and structures neatly and correctly start initializing themselves to 0 values when assigned to = {} and = {0}? I always thought they'd initialize to garbage unless explicitly told otherwise.

cppguy
  • 3,611
  • 2
  • 21
  • 36
  • They're initialized to garbage (not initialized) if you don't specify any initialization. i.e, `int foo[10];` – enobayram Aug 28 '12 at 17:01
  • Aside: If you want them all to be 57, you can (in C++): `int foo[10]; std::fill(begin(foo), end(foo), 57);` – chris Aug 28 '12 at 17:01
  • possible duplicate of [How to initialize an array in C](http://stackoverflow.com/questions/201101/how-to-initialize-an-array-in-c) – Keith Randall Aug 28 '12 at 17:02
  • 2
    I don't have a copy of K&R 1ed, but in K&R 2ed, the behavior of zero-initializing the remaining elements is explained. – James McNellis Aug 28 '12 at 17:03
  • @JamesMcNellis I don't think the remaining values were initialized at all in K&R1. (but I wouldn't swear to it---memory is a tricky thing, and it's been a very long time). – James Kanze Aug 28 '12 at 17:26

2 Answers2

12

It's been this way forever, as long as initializers existed. C89 says:

If there are fewer initializers in a list than there are members of an aggregate, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • I never knew static duration primitives also initialized themselves to 0 as well. Very interesting! Thanks! – cppguy Aug 28 '12 at 17:08
2

Where did I get this idea?

It's apparently a relatively common misconception, as I've heard the same thing from a number of other people recently. Perhaps you picked it up from somebody else with this wrong idea, or perhaps the idea is just 'intuitive'.

{} Initialization has worked as it does at least as far back as C89. I'm not aware of it ever working differently, or any compilers that ever did it differently.

For initializer lists when initializing an aggregate type (like an array):

If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from an empty initializer list (8.5.4). — Aggregates [dcl.init.aggr] 8.5.1p7

In C++ terms, when you use an empty initializer the object is value-initialized.

To value-initialize an object of type T means:

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

— if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.

— if T is an array type, then each element is value-initialized;

— otherwise, the object is zero-initialized.

                                                                                              — Initializers [dcl.init] 8.5p7

bames53
  • 86,085
  • 15
  • 179
  • 244
  • Yes, I recently learned this fact about templates. Didn't know there were other cases. Thanks! – cppguy Aug 28 '12 at 17:14