Search code examples
cc-preprocessorx-macros

Using a macro as an argument in an x-macro definition


Consider the following user-style x-macro:

#define PRIMES_X(func) \
  func(2) \
  func(3) \
  func(5)

We can use this to call a passed-in macro func repeatedly with first three primes. For example:

#define MAKE_FUNC(num) void foo ## num();
PRIMES_X(MAKE_FUNC)

Would declare the void-returning functions foo2(), foo3() and foo5().

So far, so good. Now let's say I want to use a macro in the definition of the x-macro itself, as an argument, as follows:

#define MAX_PRIME 5
#define PRIMES_X(func) \
  func(2) \
  func(3) \
  func(MAX_PRIME)

It doesn't work, because MAKE_FUNC will now try to declare void fooMAX_PRIME(), as (I suppose) the token concatenation happens without expanding MAX_PRIME.

Can I fix this so that it declares foo5() as before?


Solution

  • You can insert another level of macro-expansion (PRIMES_X2 below).

    #define MAKE_FUNC(num) void foo ## num();
    #define MAX_PRIME 5
    #define PRIMES_X(func) PRIMES_X2(func, MAX_PRIME)
    #define PRIMES_X2(func, maxPrimePar) \
      func(2) \
      func(3) \
      func(maxPrimePar)
    
    PRIMES_X(MAKE_FUNC)
    

    Output with gcc -E:

    void foo2(); void foo3(); void foo5();