Your understanding is correct. func
's a
is initialized with stack trash.
Each time you say int a;
, it will create a new variable, with no relation to similarly named variables from enclosing scopes or variables from other functions higher up the call-stack.
In your justification, you're confusing Scope and Extent. c uses lexical scoping, so while main
's "extent" (or liftime) exists through the execution of func
, it is an entirely different scope, so it refers to an entirely different variable.
Note that an "outer scope" is usually the braces outside of yours, with the outermost scope being file level.
int a; // global
void func(int a) { // parameter
int a; // function local
while (0) {
int a; // scoped in the 'while'
if (true) {
int a; // scoped in the 'if'
}
}
}
Each one of those 'a' variables shadows the other 'a's above it.
The exception (maybe the source of your confusion) being a variable declared extern int a;
. This variable specifically refers to a variable from somewhere else (different translation unit). An external declaration may be used to get the behavior you were not expecting:
An external variable may also be declared inside a function. In this case you must use the extern keyword, otherwise the compiler will consider it a definition of a local variable, which has a different scope, lifetime and initial value. This declaration will only be visible inside the function.
The exceptions to the "stack trash" rule are that static
and heap allocated variables are zero initialized (if I am not mistaken, this is enforced by the standard).
And also note that "garbage value" might be 3.