The difference of "int arr[] = {}" and "int arr[]" in C

Viewed 1733

Look the following code:

int arr[4];
for (int index = 0; index < 4; ++index) {
    printf("%d\t", arr[index]);
}

It print the random values, like this:

27224   -6784   32766   0   

But when I set arr to {}, It print zeros instead.

int arr[4] = {};
for (int index = 0; index < 4; ++index) {
    printf("%d\t", arr[index]);
}
0   0   0   0   

Why?

5 Answers

By default, the array elements are uninitialized, which means they will contain garbage values:

int arr[4];

Using a curly brace initializer, you can set the initial values explicitly, e.g.

int arr[4] = {1, 2, 3, 4};

But if the number of numbers in the braces is less than the length of the array, the rest are filled with zeroes. That's what's going on in this case:

int arr[4] = {};

Note that this is not valid in C, only in C++, but your compiler apparently allows it anyway. In standard C, you must write at least one value:

int arr[4] = {0};

When I try your code in my compiler (gcc 9.3) it gives this warning:

prog_c.c:14:12: warning: ISO C forbids empty initializer braces [-Wpedantic]
   14 | int arr[4]={};

I think that it considers this is equivalent to int arr[4]={a_single_value}; but without this single value (which is incorrect).
When you provide an initial value for less elements than the total number of elements in an array, then language considers that the missing elements are set to zero.
In your incorrect case, I guess the compiler applies the same rule for all the elements.
Your {} initialisation is considered as a partial initialisation of the array.

The both code snippets are invalid.

In the first code snippet the array has the automatic storage duration and it is not initialized. So its elements have indeterminate values. As a result the program has undefined behavior.

In the second code snippet there is used an invalid construction to initialize an array

int arr[4] = {};

you may not use empty braces in C (though it is valid in C++). This construction can be a specific compiler extension of C. A correct initialization will look like

int arr[4] = { 0 };

When there are less initializes than the number of initialized elements then the elements that have no explicit initializers are zero-initialized.

From the C Standard (6.7.9 Initialization)

21 If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

and

10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then:

— if it has pointer type, it is initialized to a null pointer;

— if it has arithmetic type, it is initialized to (positive or unsigned) zero;

— if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

— if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

So in this declaration the first element of the array is initialized explicitly by 0 and all other elements of the array are initialized implicitly by the compiler with 0.

In C such an initialization

int arr[4] = { 0 };

is equivalent to the following form of initialization

int arr[4] = { [0] = 0 };

or for example to the following form

int arr[4] = { [3] = 0 };

or you even may omit the number of elements in the array declaration as for example

int arr[] = { [3] = 0 };

That is all elements that have no explicit initializer will be zero-initialized.

The code

int arr[4];

allocates memory for an array of four ints (on the stack) but does not initialize it. The output you get is just a representation of whatever happened to be in the memory - effectively random.

int arr[4] = {}

instructs the compiler to set all the values to zero.

Alternativaly you could put

int arr[4]  = {1,2,3,4}

To initialize to specific values

By just declaring int arr [4] you are simply creating a reference. Because it is never assigned a value, the values at where this reference points to doesn't change. This is because C is an explicit language. So the values there are the values of whatever previously held the memory arr[4] is using.

By declaring int arr[4] = {}; you are explicitly setting your array equal to something. This clears the memory that you reference with arr[4] and sets it equal to the value {}. Because {} does not have any values in it, C++ defaults that to just 0's.

It looks like you have an IDE running that can compile C and C++ code. Which is why it defaulted this to 0. C is more explicit than C++, so for C code you must put values in the brackets, for example
int arr[4] = {1, 2, 3, 4};

Hope that helps!

Related