Please explain the code
#include <stdio.h>
#define A(a,b) a##b
#define B(a) #a
#define C(a) B(a)
main()
{
printf("%s\n",C(A(1,2)));
printf("%s\n",B(A(1,2)));
}
Output
12
A(1,2)
I don't understand, how the first printf evaluates to 12? Isn't it similar to the second, as C macro is simply a wrapper to B macro?
There are two operators used in the function-like macros:
##
causes a macro to concatenate two parameters.#
causes the input to be effectively turned into a string literal.In
A(a,b)
##
causes a to be concatenated with b. InB(a)
,#
effectively creates a string literal from the input. So the expansion runs as follows:Because for
C(A(1,2))
, theA(1,2)
part is evaluated first to turn into 12, the two statements aren't equal like they would appear to be.You can read more about these at cppreference.
The confusion here comes from a simple rule.
When evaluating a macro the pre-processor first resolves the macros in the arguments passed to the macro. However, as a special case, if an argument is right of
#
or adjacent to##
, it doesn't resolve macros within such arguments. Such are the rules.Your first case
The pre-processor first applies the
C(a)
macro, which is defined asB(a)
. There's no#
or##
adjacent to the argument in the definition (none of them inB(a)
at all), thus the pre-processor must resolve macros in the argument:The definition of
A(a,b)
isa##b
which evaluates into12
.After the macros in the arguments of the
C(a)
macro are evaluated, the C macro becomes:The pre-processor now resolves the
C(a)
macro, which according to its definition becomesOnce this is done, the pre-processor evaluates macros inside the result once again and applies the
B(a)
macro, so the result becomesYour second case
Similar to the first case, the pre-processor first applies the
B(a)
macro. But this time, the definition of the macro is such that the argument is preceded by#
. Therefore, the special rule applies and macros inside the argument are not evaluated. Therefore, the result immediately becomes:The preprocessor goes over the result again trying to find more macros to expand, but now everything is a part of the string, and macros don't get expanded within strings. So the final result is:
C preprocessor has two operators # and ##. The # operator turns the argument of a function like macro to a quoted string where ## operator concatenates two identifiers.
As mentioned in Wikipedia in C-preprocessor :
Also, from C-FAQ Question 11.17 :
So, similarly, going along these lines :
Whereas, in the first case, only 1 level of stringification is plainly done as per definition of B(a)(since it gets stringified immediately because of #)