0

I have #defined a preprocessor constant called CurrentClass.
The macro Method reads this constant to build a method declaration for the current class.

#define CurrentClass Foo
#define Method(x) \
    CurrentClass ## _ ## x

void Method(bar)() {

}

The preprocessor produces the following result:

void CurrentClass_bar() {

}

Obviously, CurrentClass_bar here should be Foo_bar.
The following on the other hand produces the correct result.

#define Method(class, x) \
    class ## _ ## x

void Method(Foo, bar)() {

}

For some reason, Method can't concatenate the constant CurrentClass with something else. CurrentClass alone produces the desired Foo string.

Any idea what is happening here?

AstroCB
  • 12,337
  • 20
  • 57
  • 73
IluTov
  • 6,807
  • 6
  • 41
  • 103

1 Answers1

2

You have to expand it twice

#define xx(x0,x1) x0 ## _ ## x1
#define x(x0,x1) xx(x0,x1)
#define Method(y) \
    x(CurrentClass,y)
ensc
  • 6,704
  • 14
  • 22
  • Awesome! Do you know why this is necessary? – IluTov Oct 31 '14 at 23:17
  • 1
    @NSAddict I probably should make this an answer. There is an exception to when macro arguments get expanded. See this [link](http://web.mit.edu/rhel-doc/3/rhel-cpp-en-3/macro-pitfalls.html) . Scroll to `3.9.6. Argument Prescan`. It says `Macro arguments are completely macro-expanded before they are substituted into a macro body, unless they are stringified or pasted with other tokens` . In your example you use ## concatenate so the pre-scan of the arguments doesn't cause expansion. By splitting it up into 2 macros the first expands the argument and the second concatenates. – Michael Petch Oct 31 '14 at 23:47
  • 1
    @NSAddict : To observe that the concatenations prevents the argument pre-scan take your original example `CurrentClass ## _ ## x` and replace with `CurrentClass x` . Although this experiment isn't what you want to do, review the c preprocesor output and you should notice that you get `Foo bar()` . It expanded because I removed the ## (concatenation). – Michael Petch Oct 31 '14 at 23:55