Nested ## Statement in C Preprocessor
Case 1)
#define CONCATENATE(x,y) x##y
CONCATENATE (a, CONCATENATE (b, c)) gives aCONCATENATE (b, c).
Case 2)
#define CONCATENATE(x,y) x##y
#define CONCATENATE2(x,y) CONCATENATE(x,y)
CONCATENATE2 (a, CONCATENATE2 (b, c)) gives abc.
Why doesn't case 1 work? And what does case 2 do?
Please explain step by step the procedure.
source to share
The GCC docs explain it this way:
Macro arguments are fully expanded by macros before they are replaced in a macro object, unless they are collapsed or inserted with other tokens.
(in italics)
Operands of the ## (token in pasting) operator, on the other hand, will not be macro expanded and then pasted together. So considering
CONCATENATE(a,CONCATENATE(b,c))
the preprocessor does not expand CONCATENATE(b,c)
to expand the outer body of the macro, because it is the ## operand. The preprocessor instead splices the marker before rescanning to expand macros, so
a ## CONCATENATE(b,c)
becomes
aCONCATENATE(b,c)
before rescanning, and there is no aCONCATENATE macro (but if it did, it would be expanded).
On the other hand, for
CONCATENATE2(a,CONCATENATE2(b,c)),
the argument is CONCATENATE2(b,c)
not an operand of the ## (or #) operator, so it expands before being replaced into the body of the macro, which ultimately gives
CONCATENATE(a, bc)
as the first extension of an external macro. This is re-scanned for further extensions, which gives
abc
source to share
When macros are used in a self-referential manner (or circular), as for CONCATENATE
, they do not expand recursively. That's why:
CONCATENATE(a,CONCATENATE(b,c))
gives aCONCATENATE(b,c)
.
In the second case, decomposition CONCATENATE2
is performed after processing CONCATENATE
. Hence, you get the right result.
Self-referential use of macros works great in most cases. The exceptions are token insertion and screening.
For example, if you have:
#define #define foo(x) int x
then
foo(foo(x));
expands to:
int int x;
If you have:
#define STR(y) #y
then
STR(STR(abcd));
expands to:
"STR(abcd)";
More details:
https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html
https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification
source to share