0

I'm working on a project where I have code like the following:

#define NAME() Array

inline NAME()* NAME()_init (void* arg0){return (NAME()*)Object_init(arg0);}

But I get the following result:

inline Array* Array _init (void* arg0){return (Array*)Object_init(arg0);}

With a space between the "Array" and the "_init" Because this is a function name, I obviously do not want the space. Does anyone know how to get the space out?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Maz
  • 3,375
  • 1
  • 22
  • 27

2 Answers2

2

The only way to combine two tokens into one (e.g., to combine the result of invoking NAME() and _init) is to use the concatenation operator (##). You'll need to do something like so:

#define REAL_CONCATENATE(x, y) x ## y
#define CONCATENATE(x, y) REAL_CONCATENATE(x, y)

#define NAME() Array
inline NAME()* CONCATENATE(NAME(), _init) (void* arg0){return (NAME()*)Object_init(arg0);}

Yes, the extra level of indirection is necessary.

Note that you don't need to use a function-like macro if you take no parameters, so you could just as easily use:

#define NAME Array
inline NAME* CONCATENATE(NAME, _init) (void* arg0){return (NAME*)Object_init(arg0);}
Community
  • 1
  • 1
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • It's called token pasting rather that concatenation - string concatenation occurs after tokenisation, pasting before, and doesn't require any operator. – Pete Kirkham Jun 12 '10 at 17:37
  • @Pete: Both the C and C++ language standards use the word _concatenate;_ that doesn't mean that _token concatenation_ is the same thing as _string literal concatenation_ (or any other form of concatenation, for that matter). – James McNellis Jun 12 '10 at 17:40
1

You should change the semantics in something like this:

#define NAME(X) Array##X
inline NAME()* NAME(_init) (void* arg0){return (NAME()*)Object_init(arg0);}

EDIT: At least it works with GNU cpp.

EDIT2: tried also with -ansi -pedantic and it seemed to work without warning...

ShinTakezou
  • 9,432
  • 1
  • 29
  • 39