tags:

views:

120

answers:

5

code:

 #define f(a,b) a##b
 #define g(a)   #a
 #define h(a) g(a)

 main()
 {
      printf("%s\n",h(f(1,2)));  //[case 1]
      printf("%s\n",g(f(1,2)));  //[case 2]
 }

output:

12
f(1, 2)

Why is the output not same in both cases?

[I understood the concatenation (a##b) and string conversion (#a) here, but I did not get why the output is different in both cases.]

+1  A: 

This is probably the order of evaluation. In the first case h and f get evaluated in the first pass to g and 12. The second pass of macro evaluation would then convert that to 12. In the second case, g directly evaluates f(1,2) into a string.

Rohith
yes, I understand that. But why does that happen the way you just mentioned?
Amoeba
A: 

the preprocessor expands your code to

main()
{
     printf("%s\n","12");  //[case 1]
     printf("%s\n","f(1,2)");  //[case 2]
}
Vijay Sarathi
Thats for sure. The answer is why?
RED SOFT ADAIR
A: 

C macros are not functions. It's simple text substitution. Just substitute a in g(a) with "f(1, 2)" and that's your answer.

ihuk
so in `case1`, `h(f(1,2))` becomes `g(f(1,2))`. So, the results should be the same!
Amoeba
No since parameters after # are not expanded.
ihuk
+7  A: 

The relevant part of the spec is:

6.10.3.1

"After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded."

In other words, when macro parameters are replaced, there is a round of macro expansion on the argument first, unless the parameter appears with # or ##.

So g(blah) just stringifies blah. h(blah) first macro-expands blah, then stringifies it.

The difference is particularly relevant when you want to stringify macro names:

printf("The value of the " g(NULL) " macro is " h(NULL));
Steve Jessop
@onebyone thanks for quoting the spec.
Amoeba
+1  A: 

When a function style macro is expanded, any instances of parameters in the replacement list which aren't preceded by a # or immediately adjacent to a ## are replaced by the corresponding argument after macro expansion. Macro expansion doesn't happen for parameters which follow a # or are adjacent to a ##. If there are any macros left in the expansion then macro expansion happens recursively on the replacement until there are no macros remaining. (The expansion of any macro won't expand itself during its expansion at any level of nesting so you can't get any infinite recursion.)

In your example, g(f(1,2)) becomes # of f(1,2) (no expansion of macro argument) which is "f(1, 2)", a string literal.

h(f(1,2)) becomes g( 12 ) because f(1,2) undergoes macro expansion, there is a remaining macro in this expansion, so this is expanded again and g( 12 ) becomes "12".

Charles Bailey