Scope and Storage Classes
Where a variable is visible, how long it lives, and what auto, static, extern and register mean.
Every C variable has a scope (where in the code its name is visible) and a lifetime (how long its storage exists). The storage class keywords control them.
| Storage class | Declared | Scope | Lifetime | Default initial value |
|---|---|---|---|---|
auto (the default for locals) | inside a block | that block | until the block ends | garbage (indeterminate) |
register | inside a block | that block | until the block ends | garbage; you cannot take its address |
static (local) | inside a block | that block | the whole program | 0 |
static (global) | outside functions | this file only | the whole program | 0 |
| global (no keyword) | outside functions | whole program (with extern in other files) | the whole program | 0 |
extern | anywhere | declares a global defined elsewhere | — | — |
Block scope and shadowing
A variable declared inside { } exists only inside those braces. An inner variable with the same name shadows the outer one.
int x = 100; /* global */
int main(void) {
printf("global x = %d\n", x);
int x = 10; /* local x shadows the global one */
{
int x = 1; /* shadows the outer local x */
printf("inner block x = %d\n", x);
}
printf("main's x = %d\n", x);
return 0;
}
global x = 100 inner block x = 1 main's x = 10
static local variables keep their value
An ordinary local variable is created fresh on every call. A static local is created once, initialised once, and keeps its value between calls. This is one of the most frequently asked C topics in GATE.
int counter(void) {
static int calls = 0; /* initialised only once */
int fresh = 0; /* re-created on every call */
calls++;
fresh++;
printf("calls = %d, fresh = %d\n", calls, fresh);
return calls;
}
int main(void) {
counter();
counter();
counter();
return 0;
}
calls = 1, fresh = 1 calls = 2, fresh = 1 calls = 3, fresh = 1
Globals, static globals and extern
In a program made of several .c files:
/* file a.c */
int shared = 5; /* global: other files may use it */
static int hidden = 7; /* static global: visible only inside a.c */
/* file b.c */
extern int shared; /* declaration: "shared is defined in another file" */
void show(void) { printf("%d\n", shared); } /* OK */
/* using hidden here would fail to link */
static on a global (or a function) gives it internal linkage: it is private to its file. This avoids name clashes in large programs.
Recursion with static variables
Static variables are shared by all calls of a function, including recursive ones. Trace such code carefully.
int f(int n) {
static int total = 0;
if (n == 0) return total;
total += n;
return f(n - 1);
}
int main(void) {
printf("%d\n", f(4)); /* 4 + 3 + 2 + 1 */
printf("%d\n", f(2)); /* total was NOT reset: 10 + 2 + 1 */
return 0;
}
10 13
GATE-style practice questions
What does the following program print?
int fun(void) {
static int n = 5;
return n--;
}
int main(void) {
int a = fun();
int b = fun();
int c = fun();
printf("%d\n", a + b + c);
return 0;
}
Show answer and explanation
Answer: 12n is static, so it survives between calls and is initialised to 5 only once. return n-- returns the old value and then decrements, so the three calls return 5, 4 and 3. Their sum is 12.
What does the following program print?
int x = 10;
void change(void) {
int x = 20;
x++;
}
int main(void) {
change();
x += 5;
printf("%d\n", x);
return 0;
}
Show answer and explanation
Answer: 15Inside change(), the local x (20) shadows the global, so x++ changes only the local copy, which disappears when the function returns. main then adds 5 to the global x: 10 + 5 = 15.
What does the following program print?
int count(int n) {
static int calls = 0;
calls++;
if (n <= 1) return calls;
return count(n / 2);
}
int main(void) {
printf("%d ", count(16));
printf("%d\n", count(4));
return 0;
}
Show answer and explanation
Answer: Bcount(16) recurses through 16, 8, 4, 2, 1: five calls, so it returns 5. The static counter is not reset, so count(4) adds three more calls (4, 2, 1) and returns 8.
Which statements about storage classes in C are true? (Select all that apply.)
Show answer and explanation
Answer: A, B, DA static global has internal linkage, so other files cannot see it, even with extern. The other three statements are rules of the C standard.