Search code examples
cvariablesstaticlocal-variablesstatic-variables

Are uninitialized local variables in C static by default?


I recently learnt about the static variables, that they retain their values in between various function calls. Then I wrote some code to test it, then hopefully it worked perfect. But then I accidentally removed the static keyword at the beginning of the declaration of the local variable and there came the actual problem. The output of both the programs are similar, besides the absence of the static keyword during the declaration.

Code without any static declaration:

#include <stdio.h>

void up();

int main(){
    up(); //Output: 1
    up(); //Output: 2
    return 0;
}

void up(){
    int stvar;
    stvar++;
    printf("%d\n", stvar);
}

Code with static declaration:

#include <stdio.h>

void up();

int main(){
    up(); //Output: 1
    up(); //Output: 2
    return 0;
}

void up(){
    static int stvar;
    stvar++;
    printf("%d\n", stvar);
}

Then finally I tried this one, by just initializing the local variable:

#include <stdio.h>

void up();

int main(){
    up(); //Output: 1
    up(); //Output: 1
    return 0;
}

void up(){
    int stvar = 0;
    stvar++;
    printf("%d\n", stvar);
}

This time the local variable shows it natural behaviour. I just wanted to know if uninitialized local variables are static by default?


Solution

  • No, they are not static by default. In principle, the initial value can be anything at all. Using the value could even be undefined behaviour. In practice, the compiler picks a memory location for the variable on the stack, and the variable's initial value is whatever happens to already be in that memory location.

    Since you don't run any other code between the first up() and the second up(), in practice your program is likely to pick the same location twice and therefore it still has the previous value. If you called another function in between, that function's local variables would go in the same space previously used by up()'s local variables, which would overwrite the value from the first up().

    You certainly can't rely on it. Even if you don't call any other functions in-between, the compiler might add one "secretly" (for various reasons). Or the compiler may decide to adjust the stack between the two calls to up so each call might get a different stack location for its local variables.

    You also aren't guaranteed that the first value is 0. Because it's whatever happens to be at that memory location already, it could be something left over from a previous function. main isn't the first function that gets called; there is some function in the standard library which does set-up work before it calls main.