Skip to content

Intermediate Gotchas

The Macro String That Did Not Expand

one helper layer changes the text entirely

#define NAME Ada
#define TEXT(value) #value
#define EXPANDED_TEXT(value) TEXT(value)

int main() {
  std::cout << TEXT(NAME) << '\n';
  std::cout << EXPANDED_TEXT(NAME) << '\n';
}

Run it. Do both strings say Ada?

Answer
NAME
Ada

Stringification kept the first spelling.

Why

When a macro parameter is an operand of #, the preprocessor stringifies its unexpanded tokens. TEXT(NAME) therefore becomes "NAME". In EXPANDED_TEXT, the outer macro expands NAME before it produces TEXT(Ada), so the inner macro finally stringifies Ada. GCC emits no warning under -Wall -Wextra.

The fix

Use an expansion layer whenever the argument may itself be a macro:

#define STRINGIFY_INNER(value) #value
#define STRINGIFY(value) STRINGIFY_INNER(value)

Takeaway: # stringifies the spelling it receives; use a second macro to expand first.

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry