Macro prescan funda

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)))) );

return 0;

}

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.
Hence,
=> 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(g(12)))
=> h(h(“12”)) (12 becomes the string)
=> h(g(“12”))
=> h(“\”12\””) (stringising “12”, causes escape characters \ to come for double-inverted commas, first and last commas being the stringifiers)
=> g(“\”12\””)
=> “\”\\\”12\\\”\”” (as a string)
“\”\\\”12\\\”\”” comes in 3rd printf
So output is: “\”12\””

Advertisements

One comment on “Macro prescan funda

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s