Fundamentals 7 min read

Understanding C Macro Expansion: When Parameters Expand and When They Don’t

This article explains the C preprocessor's macro‑expansion rules, detailing when macro arguments are expanded, how replacement‑list macros behave, special cases involving the # and ## operators, and provides step‑by‑step examples and techniques for controlling expansion.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Understanding C Macro Expansion: When Parameters Expand and When They Don’t

Macro Expansion Rules

In the C preprocessor, when a macro argument is itself a macro, its expansion follows a two‑step process: first the argument is expanded (parameter replacement), then the replacement list is processed. Symbols in the replacement list are further expanded unless they appear as operands of the stringizing operator # or the token‑pasting operator ##.

Parameter expansion timing

During macro invocation the preprocessor substitutes actual arguments for formal parameters.

If an argument is a macro, it is expanded before substitution.

Replacement‑list expansion

Each token in the replacement list is examined; macro tokens are expanded.

A macro parameter used with # or ## is not expanded.

Key rules

Parameter expansion precedes replacement‑list expansion.

After substitution, the resulting tokens are expanded again unless protected by # or ##.

Examples

Example 1 – parameter expands first

#define A 123
#define PRINT(x) printf("%d
", x)

Invocation: PRINT(A); Parameter replacement: A expands to 123.

Replacement‑list expansion: 123 replaces x in the printf call, yielding

printf("%d
", 123);
123

Example 2 – stringizing prevents expansion

#define A 123
#define STRINGIFY(x) #x

Invocation: printf("%s\n", STRINGIFY(A)); Parameter replacement: A is not expanded because STRINGIFY uses #.

Replacement‑list expansion: The result is

printf("%s
", "A");
A

Example 3 – token‑pasting prevents expansion

#define A 123
#define CONCAT(x, y) x##y

Invocation: CONCAT(A, B); Parameter replacement: A is not expanded because CONCAT uses ##.

Replacement‑list expansion: Tokens A and B are concatenated, producing AB, not 123B.

AB

Forcing expansion before # or ##

Introduce an intermediate helper macro that performs the stringizing or concatenation after a first level of expansion:

#define STRINGIFY(x) STRINGIFY_HELPER(x)
#define STRINGIFY_HELPER(x) #x

#define STRINGCAT(x, y) STRINGCAT_HELPER(x, y)
#define STRINGCAT_HELPER(x, y) x##y

These two‑step macros ensure that arguments are fully expanded before the operators are applied.

Why two‑step macros are required

The preprocessor expands macro arguments only once unless an extra level of indirection is provided.

Direct definitions such as #define STRINGIFY(x) #x or #define CONCAT(x, y) x##y would operate on the raw tokens, ignoring any nested macro expansions.

Summary

The C preprocessor follows a predictable two‑step expansion process: macro arguments are expanded before being placed into the replacement list, and symbols in the replacement list are further expanded unless they appear as operands of # or ##. Using helper macros provides the necessary indirection to obtain the expanded value when stringizing or token‑pasting.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CC languagemacroMacro ExpansionPreprocessorstringifyconcatenation
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.