11

I have a program.

#include <stdio.h>

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

int main()
{
      printf("%s\n",h(f(1,2)));
      printf("%s\n",g(f(1,2)));
      return 0;
}

This program working properly and giving output as:

12
f(1, 2)

I don't understand how compiler giving this output.

What is the function of # in a##b and #a?

AstroCB
  • 12,337
  • 20
  • 57
  • 73
gangadhars
  • 2,584
  • 7
  • 41
  • 68
  • http://stackoverflow.com/questions/16989730/c-stringify-how-does-it-work – Karoly Horvath Oct 05 '13 at 13:47
  • @YuHao , I'm really sorry. I searched for this question. I didn't get any related. because i don't know # is called stringify. – gangadhars Oct 05 '13 at 14:03
  • @SGG Hey, that's all right because it's hard to search for this question as there's no particular keyword. I remember seeing this program before and still spent several minutes to find the duplicate:) Even knowing the basic usage of `#` and `##`, this question is still hard to get. – Yu Hao Oct 05 '13 at 14:08

3 Answers3

12

The ## concatenates two tokens together.

The important thing is it can only be used in the preprocessor.

The # operator is used to stringify tokens.

For example:-

#(a ## b) which becomes #ab which becomes "ab"

So h(f(1,2)) becomes "f(1,2)"

Also note that # and ## are two different operators.

The preprocessor operator ## provides a way to concatenate actual arguments during macro expansion. If a parameter in the replacement text is adjacent to a ##, the parameter is replaced by the actual argument, the ## and surrounding white space are removed, and the result is re-scanned.

Also check this Concatenation for more details.

From here:-

Stringification

Sometimes you may want to convert a macro argument into a string constant. Parameters are not replaced inside string constants, but you can use the '#' preprocessing operator instead. When a macro parameter is used with a leading `#', the preprocessor replaces it with the literal text of the actual argument, converted to a string constant. Unlike normal parameter replacement, the argument is not macro-expanded first. This is called stringification.

There is no way to combine an argument with surrounding text and stringify it all together. Instead, you can write a series of adjacent string constants and stringified arguments. The preprocessor will replace the stringified arguments with string constants. The C compiler will then combine all the adjacent string constants into one long string.

Community
  • 1
  • 1
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • +1 You may want to mention that `#` and `##` are two different operators. – Sergey Kalinichenko Oct 05 '13 at 13:46
  • Why the difference in results if we have almost identical calls? – this Oct 05 '13 at 13:46
  • 1
    @self. How they are "almost identical"? 2*12 and 2+12 are as well "almost identical" and produce completely different results. – glglgl Oct 05 '13 at 13:48
  • @glglgl You explanation is useless. – this Oct 05 '13 at 13:49
  • 2
    @self. No. It shows that a seemingly minor difference can make a significant difference. Concerning the question, `f(1,2)` produces `12`. But `g()` just takes its argument and makes it a string, producing `"f(1, 2)"` (the space probably comes from the lexer or the parser). But if you feed `h()` with the `f()` call, you have one level of indirection more: `h()` references to `g()`, during which process the `f(1,2)` is expanded to `12`, which is what `g()` now stringizes, leading to the equivalent of `"12"`. – glglgl Oct 05 '13 at 14:16
4

## is called "token-pasting" operator, or "merging" operator which can be used to combine two tokens to form an actual argument.

# is called Stringizing Operator which "converts macro parameters to string literals without expanding the parameter definition".

These are generally called Preprocessor Operators. There exists a few more preprocessor operators like these. Check out Preprocessor Operators in C (http://msdn.microsoft.com/en-us/library/wy090hkc.aspx) for more explanation.


Also checkout http://msdn.microsoft.com/en-us/library/3sxhs2ty.aspx and the "see also" section of that page for more information on C Preprocessor.

Lid
  • 71
  • 5
4

let me break it down for you :

#define f(a,b) a##b //2 this macro is evaluated first with a = 1 and b = 2 it concatenates them and returns 12
#define g(a)   #a //4 g turns 12 into "12" (string)
#define h(a) g(a) //3 back to h which now has a = 12 and call g()

int main()
{
      printf("%s\n",h(f(1,2)));//1 printf calls the macro h() and gives it the macro f() as an argument 
      printf("%s\n",g(f(1,2)));// g here turns f(1,2) into "f(1,2)" (string)
      return 0;
}
Farouq Jouti
  • 1,657
  • 9
  • 15
  • Generally right, but after (1) comes first the `h()` definition as (2), which in turn "activates" `f()`, which would be (3) and then `g()` (4). – glglgl Oct 05 '13 at 14:19