17

The C99 standard document has the following example in the section related to the ## preprocessing operator:

In the following fragment:

#define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)

char p[] = join(x, y); // equivalent to
                       // char p[] = "x ## y";

The expansion produces, at various stages:

join(x, y)
in_between(x hash_hash y)
in_between(x ## y)
mkstr(x ## y)
"x ## y"

In other words, expanding hash_hash produces a new token, consisting of two adjacent sharp signs, but this new token is not the ## operator.

I don't understand why the substitution of hash_hash produces ## and not "##" or "#""#". What role are the single hashes before and after the double hash playing?

Any responses greatly appreciated.

a3f
  • 8,517
  • 1
  • 41
  • 46
deStrangis
  • 1,912
  • 1
  • 18
  • 25
  • 3
    single hashes before and after ## are just chars, and ## (token) will make them into two chars ## (not into token). after applying a mkstr to them, they will be converted to string of "##" – osgx Jul 06 '11 at 10:50

1 Answers1

21

The ## in # ## # acts like an escape sequence in this expression. It concatenates the leftmost and the rightmost # to finally produce the token ##. Simply defining the macro as ## would cause an error since the concatenation operator expects two operands.

Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130
  • 1
    How does it decide that `# ## #` means `##` and not `"##"` followed by a syntax error (because the remaining `#` does not have a right operand)? - Does `##` have precedence over `#`? – not-a-user May 06 '17 at 12:48
  • After this happens, why it doesn't cause undefined behaviour? Since "##" is not a valid preprocessing token. – Eray Xx Aug 12 '21 at 13:03