Variable Scope Interview Questions for Embedded C: Quiz and Code Challenges
62 questions: multiple choice, fill-in-the-blank, predict-the-output table, true/false, 6 code challenges with real output and 12 detailed interview answers. Treat it as a model for variable scope interview questions.
62
Questions
Beginner → Advanced
Level
Live score
Auto-graded
Live Score Tracker
0 Correct
0 Wrong
0 Attempted
Answer the auto-graded questions (MCQ, fill-in, true/false) to see your score.
Section 1: Multiple Choice Questions — Scope, Lifetime and Linkage
These variable scope interview questions in multiple-choice form check the vocabulary every embedded C interview assumes. Click an answer; the explanation always appears.
1. Where can a variable declared inside a function be used?
Block scope runs from the declaration to the closing brace.
2. What is the lifetime of a non-static local variable?
Automatic storage: it lives in the stack frame of one call.
3. What does static do to a local variable?
Scope is unchanged; the storage now lasts for the whole program.
4. What does static do to a file-scope variable?
File-scope variables already have program lifetime; static only hides the name from the linker.
5. Which section holds static int n; declared inside a function?
No initializer, so it is zero-initialized in .bss.
6. Two variables named x, one global and one local. Inside the function, x means:
The innermost declaration shadows the outer one.
7. Which GCC flag warns about shadowed variables?
-Wshadow is not part of -Wall; enable it explicitly.
8. A function returns &local where local is an automatic int. This is:
The frame is gone after return; GCC warns returns address of local variable.
9. How is a variable shared between a.c and b.c?
One definition, any number of extern declarations.
10. Which keyword makes a global invisible to other translation units?
Internal linkage.
11. Which of these has external linkage?
An ordinary file-scope definition is exported to the linker.
12. Where do automatic variables live on the STM32F407?
They are allocated in the call frame, usually SRAM or registers.
13. A global is modified in an ISR and read in the main loop. It should be declared:
Without volatile the compiler may cache the value in a register and never see the change.
14. Which statement about static int n = 5; inside a function is true?
The initial value is placed by the start-up code (.data copy) before main().
15. Which is the best way to limit the damage of global variables in a large firmware?
File-private state behind a small interface keeps modules independent.
16. In a recursive function with a 100-byte local array, 50 nested calls need roughly:
Each call has its own frame; stack use grows with depth.
Section 2: Fill in the Blanks
Capitalisation and spaces are ignored. Some blanks accept two spellings.
1. A name visible only between { and } has scope
Block (local) scope.
2. A variable defined outside every function has scope
File scope.
3. Storage that lasts for the whole program has storage duration
Static storage duration.
4. Storage created and destroyed with each function call has storage duration
Automatic.
5. A local that hides a global of the same name is said to it
Shadowing.
6. The GCC option that warns about shadowing is -W
-Wshadow.
7. The keyword that declares a variable defined elsewhere is
extern.
8. A pointer to a variable that no longer exists is called a pointer
Dangling pointer.
9. A file-scope static has linkage
Internal linkage.
10. A plain global has linkage
External linkage.
11. Locals are created in a frame
Stack frame.
12. Variables shared with an ISR should be declared
volatile.
Section 3: Predict the Output
Choose the printed result, or say if the program does not work. Predicting results like these is the heart of variable scope interview questions.
<td id=”por4″ data-why=”i is out of scope after the loop.” style=”padding:10px 14px;border:1px solid #e2e8f0;font-size:0.9em;”>
Code
Your answer
Result
void f(void){ static int n = 0; n++; printf("%d", n); } called 3 times: last value
013579Compile errorUndefined
void f(void){ int n = 0; n++; printf("%d", n); } called 3 times: last value
013579Compile errorUndefined
int x = 5; int main(void){ int x = 7; printf("%d", x); }
013579Compile errorUndefined
int x = 5; int main(void){ { int x = 7; } printf("%d", x); }
013579Compile errorUndefined
int main(void){ for (int i = 0; i < 3; i++); printf("%d", i); }
013579Compile errorUndefined
static int g; int main(void){ printf("%d", g); }
013579Compile errorUndefined
int *f(void){ int a = 9; return &a; } ... printf("%d", *f());
013579Compile errorUndefined
int *f(void){ static int a = 9; return &a; } ... printf("%d", *f());
013579Compile errorUndefined
Section 4: True or False
Warm-up items typical of variable scope interview questions.
1. A static local variable can be used by other functions in the same file.
Its scope is still the block; only its lifetime is extended.
2. A global variable exists for the entire run of the program.
Static storage duration.
3. A function parameter has the same scope as a local variable of the function body.
Parameters have block scope of the function.
4. Two different functions can each declare a local called i.
Their scopes do not overlap.
5. Static locals are stored on the stack.
They live in .data or .bss.
6. static on a function makes it private to its file.
Internal linkage applies to functions too.
7. A non-static local is guaranteed to keep its value between two calls.
The stack slot is reused; the value is indeterminate on the next call.
8. Global variables are safe to use freely in ISR code without any qualifiers.
Shared data needs volatile and usually atomic access.
Section 5: Code Snippet Challenges
Code-reading tasks like these are the second half of variable scope interview questions. Every answer is real compiler or program output.
Challenge 1 — Output?: Three declarations of v
#include <stdio.h>int v = 1;
int main(void)
{
printf(“%d “, v);
int v = 2;
printf(“%d “, v);
{ int v = 3; printf(“%d “, v); }
printf(“%d\n”, v);
return0;
}
What is printed?
Output:
1 2 3 2
The global 1, then the function-level local 2, then the block local 3, then back to 2 when the block ends.
Challenge 2 — Output?: Static id and automatic step
#include <stdio.h>staticint next(void)
{
staticint id = 10;
int step = 1;
id += step;
step += 5;
return id;
}
int main(void)
{
int a = next();
int b = next();
int c = next();
printf(“%d %d %d\n”, a, b, c);
return0;
}
What are the three numbers?
Output:
11 12 13
id is static, so it keeps counting from 10; step is automatic and is re-created as 1 on every call, so it adds exactly 1 each time. (Calling all three inside one printf would leave the evaluation order unspecified, which is why they are separate statements.)
Challenge 3 — Find the bug: Returning a local array
bug.c: In function ‘make_name’:
bug.c:6:12: warning: function returns address of local variable [-Wreturn-local-addr]
6 | return name;
| ^~~~
name dies when the function returns. Fixes: make it static, pass a caller-owned buffer, or return a string literal.
Challenge 4 — Find the bug: static in a header
/* cfg.h */staticint s_mode; /* in the header! *//* cfg.c includes cfg.h, main.c includes cfg.h *//* cfg.c: set_mode(3) writes s_mode *//* main.c reads… what? */
It compiles and links. What is the problem?
Run of the program:
Real output
mode = 3
Because static in a header gives every including file a private copy, cfg.c and main.c each get their own s_mode. (Here main.c only calls functions in cfg.c, so it works, but any direct access in main.c would see a different variable.) GCC with -Wunused may also warn in files that never use it. Keep the definition in the .c file and put only functions in the header.
Challenge 5 — Output?: Loop variable shadows x
#include <stdio.h>int main(void)
{
int x = 1;
for (int x = 10; x < 12; x++)
printf(“inner %d\n”, x);
printf(“outer %d\n”, x);
return0;
}
What is the output?
Output:
inner 10
inner 11
outer 1
The x declared in the for header exists only for the loop and shadows the outer x. The outer value is unchanged.
Challenge 6 — Output?: Static tick
#include <stdio.h>staticint tick(void)
{
staticint t;
return ++t;
}
int main(void)
{
int a = tick();
int b = tick();
printf(“%d %d %d\n”, a, b, tick() + tick());
return0;
}
What is printed? (Careful with the last expression.)
Output:
1 2 7
tick() increments one shared static. a = 1, b = 2, and the sum of the next two calls is 3 + 4 = 7.
Section 6: Variable Scope Interview Questions for Embedded C (with Detailed Answers)
These variable scope interview questions are the ones hiring managers use to separate memorisation from understanding. Click a question for a model answer.
Q1. What is the difference between scope and lifetime?Basic+
Scope
Lifetime
Question
Where in the source can the name be used?
When during execution does the storage exist?
Compile time or run time?
Compile time
Run time
Example
Block, file
Automatic, static
They are independent. A static local has block scope but program lifetime.
Q2. What are the storage durations in C and where does each live on an STM32F407?Basic+
Duration
Examples
Memory
Static
globals, static locals
.data / .bss in SRAM, or .rodata in flash if const
Automatic
locals, parameters
Stack (or registers)
Allocated
malloc
Heap, usually avoided in firmware
Q3. What is the effect of static on a local variable, on a global variable and on a function?Basic+
Applied to
Effect
Local variable
Storage lasts for the whole program; value kept between calls; scope unchanged.
Global variable
Internal linkage: hidden from other files.
Function
Internal linkage: the function is private to the file.
The same keyword therefore changes lifetime for locals and linkage for file-scope names.
Q4. What is variable shadowing and how do you avoid it?Basic+
A declaration in an inner scope hides an outer one with the same name. It is legal, but an assignment may silently change the wrong object. Avoid it by using distinct names (g_ prefix for globals, s_ for statics) and enabling -Wshadow in the build.
Q5. Why are global variables considered harmful in embedded code, and when are they acceptable?Intermediate+
Any function can change them, so behaviour depends on call order; they hinder testing, reuse and RTOS safety; and ISR sharing causes races. They are acceptable when they model genuinely global hardware state (a system tick, a register image) and are hidden: file-static, volatile when shared with interrupts, and accessed via small functions that can disable interrupts around multi-byte updates.
Q6. Explain the difference between a static global and a global declared in a header with extern.Intermediate+
The extern pattern gives one shared object with external linkage. A static global gives each translation unit its own private object. Using static in a header is almost always a bug because every includer silently gets a separate copy.
Q7. Why is returning a pointer to a local variable undefined behaviour? Give three safe alternatives.Intermediate+
The local is destroyed when the function returns; the pointer then refers to memory that may be reused by the next call, so reads give stale or corrupted data and writes corrupt other frames. Safe alternatives: (1) return a pointer to a static object (not reentrant), (2) let the caller supply the buffer and size, (3) return the value itself or a struct by value.
Q8. A function with static int n works in a single-task program but fails with an RTOS. Why?Intermediate+
The static is one shared object. Two tasks calling the function interleave updates to the same variable, and a context switch in the middle of n++ (read, add, write) can lose an update. Make the function reentrant: pass state through a parameter, use task-local storage, or protect the access with a mutex or critical section.
Q9. Can a static local be initialized with a non-constant expression such as the return value of a function?Advanced+
In C, no: the initializer of any object with static storage duration must be a constant expression, because it is evaluated at translation time and stored in .data. To compute a value on first use, use a flag: static int ready; static int v; if (!ready) { v = compute(); ready = 1; }. (C++ allows dynamic initialization with thread-safe guards; C does not.)
Q10. How does the start-up code on a Cortex-M make static-storage variables work?Advanced+
The linker script places initialized static data in .data with a load address in flash and a run address in SRAM, and zero-initialized data in .bss. Reset_Handler copies from the flash load address to the SRAM run address, then zeroes .bss, and only then calls SystemInit() and main(). Automatic variables need no start-up work because they are created by the function prologue on the stack.
Q11. What goes wrong if an ISR and main() share a plain (non-volatile) global flag?Advanced+
The optimiser assumes nothing else changes the variable between reads, so a loop like while (!flag) {} can be compiled to read flag once and spin forever, even though the ISR sets it. Declaring it volatile forces a real load on every access. For multi-byte or read-modify-write data, volatile is still not enough: disable the interrupt briefly or use atomics. Module 14 treats this in depth.
Q12. A teammate puts int g_state; in a header included by 20 files. It built fine five years ago and fails today. Explain.Advanced+
Older GCC defaults to -fcommon, which merged tentative definitions. GCC 10 and later default to -fno-common, so 20 definitions now produce multiple definition errors. The fix is the standard pattern: extern int g_state; in the header and exactly one definition in a .c file.
Study Plan: Using Your Score on These Variable Scope Interview Questions
Score
Meaning
Next step
90–100%
Excellent
Continue to Lesson 4.3: storage classes and memory placement.
70–89%
Good
Redo Examples 3, 6, 7 and 9.
Below 70%
Revise
Re-read theory sections 4, 5, 7 and 8, then retake the quiz.
Next lesson: Lesson 4.3 connects scope and lifetime to the four storage-class keywords and to the memory sections on the STM32F407.
Lesson 4.2 complete!
Next up: storage classes and where each variable lands in flash and SRAM.
2 Comments