Coding/Learn/c/c preprocessor macros storage classes
C Foundational Course
01.Introduction, Compilation Pipeline & Syntax
02.Variables, Primitives & Explicit Type Casting
03.Operators, Precedence & Booleans (<stdbool.h>)
04.Control Flow: If-Else, Ternary & Switch
05.Loops (For, While, Do-While) & Jump Statements
06.Contiguous Arrays & Multi-Dimensional Matrices
07.Null-Terminated Strings & <string.h>
08.User Input, scanf & fgets Buffer Safety
09.Pointers, Memory Addresses & Dereferencing
10.Functions, Prototypes & Pass-by-Pointer
11.11. Recursion & High-Speed Function Pointers
12.File Streams: Create, Write & Read (fopen/fclose)
13.Structures, Unions & typedef Aliasing
14.Memory Word Alignment & Struct Padding
15.Enums & Bitwise Manipulation (Flags & Masks)
16.Dynamic Memory: malloc, calloc, realloc & free
17.Defensive Error Handling, errno & Assertions
18.Preprocessor Macros & Storage Classes
19.Fixed-Width Types (stdint.h), Math & Time (<time.h>)
20.Capstone: High-Performance In-Memory Key-Value Engine
Course Certificate0%

Complete all lessons to earn

LearnPreprocessor Macros & Storage Classes
18 / 20 0%
Lesson 18 of 20
6 mins read

Preprocessor Macros & Storage Classes

PreviousNext Lesson
In Plain English

The C preprocessor expands macros (#define) and includes headers before compilation. Storage classes dictate variable lifetime and visibility: static preserves state across function calls and limits file visibility, while extern shares global symbols across translation units.

The Mental Model

"A static local variable is a tally counter on a kitchen fridge: every time someone enters the room and clicks it, the number keeps going up and never resets to 0."

Deep Dive: How It Works

Parameterized Macros: Literal textual replacement; always parenthesize parameters (((a) > (b)) ? (a) : (b)).

Header Guards: #ifndef / #define / #endif prevents duplicate type definitions in multiple inclusions.

static Lifetime: Keeps local variable state alive across repeated function invocations.

Syntax Blueprint

#define MAX(a, b) (((a) > (b)) ? (a) : (b))

void count(void) {
    static int n = 0;
    n++;
}

Define safe parameterized macro and static variable that persists across calls.

PointCore Rules to Remember

Point star
Macro Parentheses: Always wrap macro arguments in parentheses to prevent operator precedence bugs.
Point star
static Variable Persistence: Allocated in the data segment once; retains value throughout process lifetime.
Point star
Header Guard Best Practice: Standard guard pattern ensures headers can be safely included in any order.

Common Beginner Traps & How to Fix Them

Mistake:Macro side effects: #define SQR(x) ((x) * (x)) called with SQR(i++).

Why it happens: i++ is expanded twice, causing unintended double increments.

How to fix: Avoid passing expressions with side effects (like i++) into preprocessor macros.

Pro Tip: Use static on helper functions in .c files to keep them private and allow the compiler to inline them aggressively.

Live Interactive Example

Hit Run Code to see it live
Static Persistence and Macros
C11 / GCC 9.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Output Console
Click "Run Code" to view the rendered output.
How it works: static callCount persists between trackCounter calls, incrementing from 1 to 2.

Your Turn: Micro Challenge

No pressure! Edit the starter code below and test your solution with instant feedback.

Micro Exercise

Demonstrate Third Static Call

  • PointInvoke trackCounter() a 3rd time to demonstrate static variable persistence.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Sandbox Output
Click "Run & Check" to test your solution.

Finished reading and practicing?

Mark this lesson as completed to update your course progress.

PreviousNext Lesson
Overview100 SheetLearnCertificates