Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

local variable initialized to zero in C

Tags:

c

I thought that the local variable in C is not initialized. But when I compiled this code with gcc.

void f() {
    static int s;
    int n;

    printf("static s = %d\n", s++);
    printf("local  n = %d\n", n++);

    f();
}

main() {
    f();
}

And run this code, the partial result is:

static s = 0
local  n = 0
static s = 1
local  n = 0
static s = 2
local  n = 0
static s = 3
local  n = 0
static s = 4
local  n = 0
static s = 5
local  n = 0
...
static s = 261974
local  n = 0
static s = 261975
local  n = 0
static s = 261976
local  n = 0
static s = 261977
local  n = 0
static s = 261978
local  n = 0
static s = 261979
local  n = 0
static s = 261980
local  n = 0
static s = 261981
local  n = 0
Segmentation fault: 11

Could anyone please explain this? Or refer to a standard reference that C won't init local vars?

like image 741
wannik Avatar asked Jan 16 '14 02:01

wannik


2 Answers

Local non-static variables are not initialized -- which typically means they contain garbage.

0 is just as valid a garbage value as any other. But the initial value could just as easily have been 42 or -12345.

Just don't do that. You need to ensure that you don't read the value of any variable unless it's been initialized. Reading an uninitialized variable has undefined behavior, which means that the possible behavior is not limited to printing some arbitrary value.

A good way to do to do that is to use an explicit initializer:

int n = 0;

(Incidentally, you're missing the required #include <stdio.h>, and the correct declaration for main is int main(void).)

like image 152
Keith Thompson Avatar answered Sep 21 '22 19:09

Keith Thompson


ISO/IEC 9899:TC3 WG14/N1256 (C99 standard) section 6.7.8 clause 10:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

If an object that has static 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;
  • if it is a union, the first named member is initialized (recursively) according to these rules.

Your variable fits the first category. Indeterminate means it can be anything (including 0). Just because it is zero in the tests you have performed, does not mean it will always be or that you can rely on that behaivour. The behaivour might change even with the same compiler depending on the compilation options and optimization level.

like image 28
harmic Avatar answered Sep 22 '22 19:09

harmic