4

I came across this question in an Embedded interview question set.

#define cat(x,y) x##y

concatenates x to y. But cat(cat(1,2),3) does not expand but gives preprocessor warning. Why?

Does C not encourage Recursive Macro expansions ? My assumption is the expression should display 1##2##3. Am i wrong ?

Lee Duhem
  • 14,695
  • 3
  • 29
  • 47
Abhijit K Rao
  • 1,097
  • 1
  • 8
  • 18
  • 3
    Recursive expansion works only for one level. See here: [Self Referencial Macros](https://gcc.gnu.org/onlinedocs/cpp/Self-Referential-Macros.html#Self-Referential-Macros) and [Stringification](https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification) – 0xF1 May 28 '14 at 03:34
  • 1
    I'm sorely tempted to close this as a duplicate of [C preprocessor and concatenation](http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation), but there's just barely enough difference that I don't want to abuse the new god-like 'close-as-duplicate' powers that we've been given. It won't take much encouragement, though. – Jonathan Leffler May 28 '14 at 03:47
  • The warning is correct; you can't combine a close parenthesis with a 3 and make a token, and token concatenation has to make a token. – Jonathan Leffler May 28 '14 at 03:48
  • @JonathanLeffler I agree that it is not a duplicate of that, but ther's bound to be a dupe somewhere – M.M May 28 '14 at 04:50

1 Answers1

3

The problem is that cat(cat(1,2),3) isn't expanded in a normal way which you expect that cat(1,2) would give 12 and cat(12, 3) would give 123.

Macro parameters that are preceded or followed by ## in a replacement list aren't expanded at the time of substitution. As a result, cat(cat(1,2),3) expands to cat(1,2)3, which can't be further expanded since there is no macro named cat(1,2)3.
So the simple rule is that, macros whose replacement lists depends on ## usually can't be called in a nested fashion.

haccks
  • 104,019
  • 25
  • 176
  • 264