Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preprocessor token expansion [duplicate]

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?

like image 781
fredoverflow Avatar asked Nov 26 '10 11:11

fredoverflow


People also ask

What is ## in preprocessor?

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.

What does ## do in a macro?

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.

What does ## mean in C++?

## is called token concatenation, used to concatenate two tokens in a macro invocation.

What is preprocessor expansion?

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.


2 Answers

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

like image 184
Simone Avatar answered Oct 16 '22 05:10

Simone


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
like image 3
Ziffusion Avatar answered Oct 16 '22 07:10

Ziffusion