I was just going through a community post and saw the following C problem, and reminded me of my college days, thanks to the post-maker!
I managed to write this here; because it may come on Google search for others who are still confused with such problem. Hope my explanation helps!!
Predict and explain the output of last printf statement.
#define f(a,b) a##b
#define h(a) g(a)
#define g(a) #a
int main ()
printf (“\n%s”,g(f(1,2)) );
printf (“\n%s”,h(f(1,2)) );
printf (“\n%s”,h(h(h(f(1,2)))) );
Before we jump to find the output, let’s remember a few golden preprocessor rules defined by GNU corp. in gcc.
a) # opeartor stringises the argument.
b) ## opeartor concatenates the two arguments.
c) If an argument is stringified or concatenated, the prescan does not occur.
d) Prescan is a process in which complete macro expansion takes place.
Let’s come to the printfs one-by one:
g(f(1,2)) => matches g(a); which says a whould be stringified. No prescan takes place; just the argument f(1,2) as an string “f(1,2)” comes in printf.
So output is: f(1,2)
h(f(1,2)) => matches h(a) which calls another macro (not doing any concat or stringisation), so prescan should take place and it goes to the lower level expansions.
=> h(f(1,2)) => h(1##2) => h(12)
=> g(12) => “12” (as a string)
“12” comes in 2nd printf.
So output is: 12
h(h(h(f(1,2)))) => matches h(a); prescan should take place (because no stringisation/concatenation)
so, from lower level, we need to go up replacing the macros by their aproprite values.
h(h(h(f(1,2)))) => h(h(h(12))) (12 is juat a concatenated object, not a string)
=> h(h(“12”)) (12 becomes the string)
=> h(“\”12\””) (stringising “12”, causes escape characters \ to come for double-inverted commas, first and last commas being the stringifiers)
=> “\”\\\”12\\\”\”” (as a string)
“\”\\\”12\\\”\”” comes in 3rd printf
So output is: “\”12\””