My mental model of how the preprocessor works is apparently incomplete, and this is driving me crazy.
I want to concatenate two tokens, but the second token should be expanded first.
#define ANSWER 42
#define FOO foo_ ## ANSWER
Here, FOO
expands to foo_ANSWER
, but I want it to be foo_42
. So I define a MERGE
macro in the hopes that this would somehow expand the arguments before concatenation:
#define MERGE(x, y) x ## y
#define BAR MERGE(bar_, ANSWER)
But BAR
still expands to bar_ANSWER
instead of bar_42
. So I define another macro HELPER
:
#define HELPER(x, y) MERGE(x, y)
#define BAZ HELPER(baz_, ANSWER)
And now BAZ
is successfully expanded to baz_42
. At the moment, this seems like magic to me.
Can anyone explain this behavior to me? How do the expansion rules work exactly?
This is called token pasting or token concatenation. The ' ## ' preprocessing operator performs token pasting. When a macro is expanded, the two tokens on either side of each ' ## ' operator are combined into a single token, which then replaces the ' ## ' and the two original tokens in the macro expansion.
The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.
## is called token concatenation, used to concatenate two tokens in a macro invocation.
The preprocessor provides the ability for the inclusion of header files, macro expansions, conditional compilation, and line control. In many C implementations, it is a separate program invoked by the compiler as the first part of translation.
Read the answer to your question here:
The problem is that when you have a macro replacement, the preprocessor will only expand the macros recursively if neither the stringizing operator # nor the token-pasting operator ## are applied to it. So, you have to use some extra layers of indirection, you can use the token-pasting operator with a recursively expanded argument
Token concatenation does not expand macros when performing concatenation [ref].
To get past this, you use a level of indirection, and get the preprocessor to expand the macros before the concatenation.
#define STEP1(x, y) STEP2(x, y) // x and y will be expanded before the call to STEP2
#define STEP2(x, y) x ## y // x and y will not be expanded, just pasted
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With