Two variables, one name, one program. When an inner block declares its own x, what happens to the outer one — replaced, modified, or just… hidden? This question from our C Programming Quiz App tests variable shadowing, the scope rule that decides which x each printf can see.
The Quiz Question
int x = 5;
{
int x = 10;
printf("%d ", x);
}
printf("%d", x);
What is printed by this code?
- 5 5
- 10 10
- 10 5
- 5 10
The Correct Answer: 10 5
The inner int x = 10; declares a second, separate variable that happens to reuse the name. From its declaration to the closing }, the name x refers to the inner variable — the outer one is shadowed: still alive, still holding 5, just unreachable by name. When the block ends, the inner x is destroyed and the name snaps back to the outer variable. Verified on gcc 13.3 and Apple clang 21, clean under -ansi -Wall -Wextra:
$ gcc -ansi -Wall -Wextra shadow.c && ./a.out 10 5
Why Each Wrong Answer Is Wrong
Why not “10 10”?
This is the “assignment” reading — as if int x = 10; overwrote the outer variable. But the int makes it a declaration: a new object at a new address. The outer x never receives 10. (Drop the int and it would be an assignment — then the output really would be 10 10. One keyword decides.)
Why not “5 5”?
This reading has the inner declaration ignored — but inside the block, the innermost declaration wins unconditionally. Name lookup in C starts at the current scope and walks outward, stopping at the first match; the inner x intercepts every use of the name inside the braces.
Why not “5 10”?
Backwards on both ends: the first printf is inside the block (sees the inner 10), and the second is after it (inner x no longer exists, outer 5 is back). Shadowing follows block structure, not chronology of declaration.
Shadowing: Legal, Silent, and Worth a Warning Flag
Every pair of braces in C opens a new scope, and any scope may redeclare a name from an enclosing one — that’s the whole rule. It’s what makes local variables in different functions independent, and it’s also a quiet source of bugs: an inner declaration can hijack a name you meant to update, and the code still compiles cleanly. Notably, -Wall -Wextra say nothing about this program. The dedicated flag is -Wshadow:
$ gcc -Wall -Wextra -Wshadow shadow.c warning: declaration of 'x' shadows a previous local [-Wshadow] note: shadowed declaration is here
Both compilers support it, and codebases that care about this bug class (the Linux kernel among them) build with it. The other classic shadowing accident is a loop or parameter shadowing a global — same rule, bigger blast radius. The cleanest defense costs nothing: don’t reuse meaningful names in nested scopes, and keep scopes small enough that a duplicate name would be obvious. (Shadowing across call boundaries doesn’t exist — each function’s locals are born fresh per call, which is the static-local question‘s territory.)
Frequently Asked Questions
What is variable shadowing in C?
An inner-scope declaration reusing a name from an outer scope. Inside the inner scope, the name refers to the new variable; the outer one is hidden but unchanged, and becomes visible again when the inner scope ends.
Does the inner declaration modify the outer variable?
No — int x = 10; creates a completely separate object. The outer x keeps its 5 throughout. Without the int keyword it would be an assignment to the outer variable instead.
How do I get warned about shadowing?
Compile with -Wshadow — it’s not part of -Wall or -Wextra on either gcc or clang. It flags declarations that shadow locals, parameters, or globals.
Related Reading
- Static Local Variables in C – Why the Counter Prints 1 2 3
- Assignment vs Comparison in C – The if (x = 0) Bug
- Pass by Value in C – Why inc(n) Doesn’t Change n
- C Aptitude Questions and Answers
Recommended Books
- The C Programming Language – Kernighan & Ritchie (India) | Amazon.com
- C Programming: A Modern Approach – K.N. King (India) | Amazon.com
This question is #131 in the C Programming Quiz App — 155 questions with explanations covering basics, operators, pointers, and more.
Download on Google Play →