11

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?

wannik
  • 12,212
  • 11
  • 46
  • 58
  • 1
    The behavior is undefined; anything can happen. – arshajii Jan 16 '14 at 02:10
  • @wannik - Luck. But do not bank on it. It is undefined behaviour. Better turn on the compiler warnings – Ed Heal Jan 16 '14 at 02:11
  • Yes, undefined. See also several of the previous answers under "Related" at right. Seriously, if you want it initialized to 0, use an explicit initial value. – keshlam Jan 16 '14 at 02:14
  • Try single call twice without recursion. Some OSs like Windows zero free memory in idle process. So stack chunk may be allocated already zeroed. – Sergei Krivonos Jun 01 '17 at 10:21
  • @EdHeal I don't get a warning for this with -Wall -Wextra, what is the compiler warning flag for this? – PizzaBeer Oct 11 '19 at 14:52

5 Answers5

19

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.

Paul R
  • 208,748
  • 37
  • 389
  • 560
harmic
  • 28,606
  • 5
  • 67
  • 91
  • Thank you so much, @harmic. This is exactly what I'm looking for. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf – wannik Jan 16 '14 at 02:25
6

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).)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
3

In my experience, it might or might not be initialized to 0 depending on the compiler and the flags used during compile.

Community
  • 1
  • 1
Dannie
  • 2,430
  • 14
  • 16
2

What you're writing exhibits undefined behavior (and I assume gets you a scolding from your compiler). The fact that this compiler produced a program with this output today doesn't particularly mean anything. The compiler may just be setting all stack memory to zero. Or the stack may be advancing through previously zeroed-memory. Or the stack is staying exactly where it is (the compiler couldn't "unroll" your main, after all) and the location of n happened to be a zero word. Today.

Bandrami
  • 4,242
  • 1
  • 13
  • 12
0

If the variable is initialized inside a function it is not initialized automatically. When it's declared outside any function, it's initialized with 0.

speedyxvs
  • 111
  • 1
  • 2
  • 9