1

While debugging my program I noticed that some elements of my 2D-array contain nonzero values.

float Ak[2][2];
Ak[0][0] = 1;
Ak[1][1] = 1;

When I run this code Ak[0][0] and Ak[1][1] are 1 as expected but Ak[0][1] was 1.081 which I actually expected to be 0.

That's probably due to the fact that arrays aren't implicitly initialized. But is this always the case? Do I always have to initialize my arrays when I want specific behavior or are there some cases where the compiler does this automatically? Is it compiler dependent?

And the almost most important question: Where is this behavior specified? (I need a citation for my Thesis)

dbush
  • 205,898
  • 23
  • 218
  • 273
the-powl
  • 11
  • 2
  • 2
    Local variables don't have any default initialization. They're about as likely to start out containing 0 as any other seemingly random value. This applies both to arrays and to ordinary variables. You can read a summary of the initialization rules for different classes of variables [here](https://stackoverflow.com/questions/51329671/difference-between-static-global-variable-and-non-static-global-variable-in-c). – Steve Summit Jul 01 '21 at 19:13
  • 2
    Local non-static variables are uninitialized. Local static variables are implicitly initialized to zero, just as non-local variables are. – Tom Karzes Jul 01 '21 at 20:17

2 Answers2

4

Any variable (not just arrays) defined locally that isn't static, or more formally those with automatic storage duration, are not implicitly initialized. Those defined at file scope or with static, i.e. those with static storage duration, are implicitly initialized to 0 or NULL.

This is spelled out in section 6.7.9p10 of the C standard:

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;

And of course, just because an uninitialized variable happens to be 0 doesn't mean it doesn't contain garbage.

dbush
  • 205,898
  • 23
  • 218
  • 273
1

Variables that have automatic storage duration (variables declared in a block scope) are not initialized implicitly.

Variables that have static storage duration (variables declared in a file scope or that have the specifier static) if not initialized explicitly initialized implicitly (for arithmetic types they are zero-initialized, or for pointer types they are initialized as null pointers).

It seems you declared your array within a function

float Ak[2][2];
Ak[0][0] = 1;
Ak[1][1] = 1;

So its elements are not initialized implicitly.

You could write for example

float Ak[2][2] =
{
    [0][0] = 1.0f, [1][1] = 1.0f 
};

In this case all elements of the array will be initialized. Elements that do not have an explicit initializer will be zero-initialized.

Here is a demonstrative program.

#include <stdio.h>

int main(void) 
{
    float Ak[2][2] =
    {
        [0][0] = 1.0f, [1][1] = 1.0f 
    };

    printf( "Ak[0][0] = %f, Ak[0][1] %f, Ak[1][1] = %f\n", 
             Ak[0][0], Ak[0][1], Ak[1][1] );
    
    return 0;
}

The program output is

Ak[0][0] = 1.000000, Ak[0][1] 0.000000, Ak[1][1] = 1.000000

Alternatively you could initialize your array also the following way

float Ak[2][2] =
{
    [0] = { [0] = 1.0f }, [1] = { [1] = 1.0f } 
};
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335