c2cedge
C, Java & Python · B — C Essentials

C: Storage Classes & the Preprocessor

static, extern, the lifetime of a variable, and #define macros are perennial C interview territory — small keywords with big behavioural consequences.

Test weight: Medium–High (C)Skill: Scope & lifetimeDifficulty: Medium

Storage classes (auto, register, static, extern) control a variable's lifetime (how long it lives) and linkage/scope (where it's visible). The preprocessor runs before compilation, handling #include, #define macros and conditional compilation through pure text substitution. Both are classic interview ground.

static and the preprocessor

A static local variable keeps its value between function calls and is initialised once. A static global/function limits visibility to its own file. extern declares something defined elsewhere (shared across files). #define creates a macro the preprocessor substitutes as raw text — with no type checking.

static local retains its value
void counter(void) {
    static int count = 0;  // initialised once; persists across calls
    count++;
    printf("%d ", count);
}
// counter(); counter(); counter();  ->  1 2 3
Macros are text substitution
#define PI 3.14159
#define SQUARE(x) ((x) * (x))   // parenthesise EVERYTHING
int a = SQUARE(2 + 3);          // ((2 + 3) * (2 + 3)) = 25, thanks to parens
⚡ The edge
  • A static local variable is initialised once and keeps its value across calls — perfect for counters — while still being scoped to that function. 'static' on a global instead means 'private to this file'.
  • Macros are blind text substitution with no type checking, so always wrap parameters and the whole body in parentheses. #define SQUARE(x) x*x turns SQUARE(2+3) into 2+3*2+3 = 11, not 25 — a classic bug.
Worked example
What is the difference between a static local variable and a global variable?
  1. Both live for the whole program (static storage duration).
  2. A global is visible everywhere (across files, unless made static); a static local is visible only inside its function.
  3. So static local gives you persistence without exposing the variable — lifetime of a global, scope of a local.
Worked example
Why prefer parentheses in macros like #define SQUARE(x) ((x)*(x))?
  1. Macros substitute text literally before compilation, ignoring precedence.
  2. Without parentheses, SQUARE(2+3) expands to 2+3*2+3, which is 11, not 25.
  3. Wrapping each parameter and the whole expression in parentheses preserves the intended grouping.
⚠ Watch out
  • Macro side effects: SQUARE(i++) increments i twice — macros re-evaluate their arguments.
  • 'static' means different things for a local (persistence) vs a global/function (file-private).
  • The preprocessor runs before compilation and does no type checking — macro bugs aren't caught like function bugs.
Practice this — take a timed mock →
1,300+ questions, scored, with a weak-area report.
Know who's ready. Not who finished.
HomeLibraryPrivacyTerms