Ch3.14: stringify
Macros and Token Manipulation
The C++ preprocessor provides two special operators that manipulate tokens:
#— stringification##— token pasting
These operators work only inside #define macros. They are
powerful but must be used carefully.
Stringification: #
The # operator converts a macro argument into a string
literal.
#define STR(x) #x
println(STR(hello world));
Output:
hello world
The argument is not evaluated — it is turned into text exactly as written.
Example: printing expressions
#define SHOW(expr) println(#expr, " = ", (expr))
SHOW(2 + 3);
SHOW(10 * 20);
Output:
2 + 3 = 5
10 * 20 = 200
Token Pasting: ##
The ## operator concatenates two tokens into one.
#define MAKE_NAME(prefix, id) prefix##id
int MAKE_NAME(var, 1) = 42; // becomes: int var1 = 42;
Token pasting is often used to generate variable names or function names.
Example: generating enum-to-string helpers
#define CASE_TO_STRING(x) case x: return #x;
switch (c) {
CASE_TO_STRING(red)
CASE_TO_STRING(green)
CASE_TO_STRING(blue)
}
Combining # and ##
You can combine both operators to build more complex macros.
#define MAKE_GETTER(name) \
int get_##name() { \
println("getting " #name); \
return name; \
}
int value = 123;
MAKE_GETTER(value)
Expands to:
int get_value() {
println("getting " "value");
return value;
}
Macro Pitfalls
1. No type checking
Macros operate on text, not types. Errors may appear only after expansion.
2. Side effects
Macros may evaluate arguments multiple times.
#define SQR(x) ((x) * (x))
SQR(++i); // expands to ((++i) * (++i))
This increments i twice — almost never intended.
3. Hard to debug
Debuggers show expanded code, not macro definitions.
4. Token pasting can create invalid code
#define BAD(x) x##123abc // invalid token
The compiler will error after expansion.
Safe Usage Patterns
- Use parentheses around macro arguments.
- Use
#for debugging helpers. - Use
##only when necessary. - Prefer
constexprand templates in modern C++.
Macros are powerful but should be used sparingly.
Key takeaways
- # turns macro arguments into string literals.
- ## pastes tokens together.
- Macros operate on text, not types.
- Side effects and multiple evaluations are common pitfalls.
- Prefer modern C++ features when possible.