4

https://en.cppreference.com/w/cpp/language/zero_initialization shows that zero-initialization happens in the following scenario:

int array[32] = {};

; but never says anything about this:

int array[32] = { 0 };

Does the latter also zero-initialize the whole array in c++, or only the first element? If so, is it also true for structs?

6
  • 2
    The latter is particularly peculiar to use because any other value initializes only the first element (and zeroes the rest, thx to @ChrisDodd for clarifying that)... Commented Jan 25, 2020 at 20:56
  • 3
    For what it's worth int array[4] = { 1 }; would produce {1, 0, 0, 0} so don't think the latter syntax initializes the whole array with that value. Commented Jan 25, 2020 at 20:57
  • 2
    @Resurrection: not true -- any array initializer that is smaller than the array will zero initialize all the trailing (unspecified) elements. Commented Jan 25, 2020 at 20:58
  • a C statement like: int array[32] = {}; results in the compiler outputting the following: "untitled2.c:1:17: warning: ISO C forbids empty initializer braces [-Wpedantic]" suggest: int array[32] = {0}; Notice the initializer inside the braces. However, if you want to use a value other than 0, suggest: for( size_t i = 0; i< 32; i++ ) { array[i] = 1; } Commented Jan 26, 2020 at 13:34
  • the C language and the C++ language are very different, (and getting further apart with each new release) Please pick one and erase the other tag Commented Jan 26, 2020 at 13:40

4 Answers 4

6

ISO/IEC N489 §9.4.1 states

  • (5) For a non-union aggregate, each element that is not an explicitly initialized element is initialized as follows:

    • (5.1) If the element has a default member initializer (11.4), the element is initialized from that initializer.

    • (5.2) Otherwise, if the element is not a reference, the element is copy-initialized from an empty initializer list (9.4.4).

    • (5.3) Otherwise, the program is ill-formed.

§9.4.4 states

  • (3.11) Otherwise, if the initializer list has no elements, the object is value-initialized.

Value-initialization of a scalar leads to its zero-initialization. Thus, the second one explicitly initializes with 0 only array[0] and the rest of the elements will be zero-initialized.


Thus, the following code

int array[4] = {13};

initializes array with values

{13, 0, 0, 0}
Sign up to request clarification or add additional context in comments.

Comments

2

Does the latter also zero-initialize the whole array in c++, or only the first element?

Yes.

The first style is C++ style.

The second one is old C style.

Both zero initialise the whole array elements (not just the first element).

If so, is it also true for structs?

Yes.

3 Comments

Both zero initialise the whole array elements this can be misleading. It's true only if the value used in the initializer is 0. Otherwise, any array initializer shorter than the size of the array will initialize trailing values with 0.
Yes that's what the question is about {0}. What you said is correct (if the value used in the initialised is something else), thanks
"The second one is old C style" -- is there a new C style for this?
1

...but never says anything about this

It does. This is actually aggregate initialization.

As per cppreference:

If the number of initializer clauses is less than the number of members and bases or initializer list is completely empty, the remaining members and bases are initialized by their default member initializers, if provided in the class definition, and otherwise by empty lists, in accordance with the usual list-initialization rules (which performs value-initialization for non-class types and non-aggregate classes with default constructors, and aggregate initialization for aggregates). If a member of a reference type is one of these remaining members, the program is ill-formed.

This guaruntees that the remaining elements of the array are initialized with empty lists. For int (which is scalar) this initializes it to zero. For structs this would perform value-initialize if the struct is not an aggregate or aggregate-initialize otherwise.

Comments

1

Use CppInsights to see what actually happens:

This:

int main()
{
    int array0[5];
    int array1[5] = {};
    int array2[5] = { 0 };
    int array3[5] = { -1 };
    int array4[5] = { 1, 2 };
}

is equivalent to:

int main()
{
  int array0[5];
  int array1[5] = {0, 0, 0, 0, 0};
  int array2[5] = {0, 0, 0, 0, 0};
  int array3[5] = {-1, 0, 0, 0, 0};
  int array4[5] = {1, 2, 0, 0, 0};
}

So, int array2[5] = { v } explicitly initializes the first element with v, and default initializes all other elements.

Comments