使用宏作为x-macro定义中的参数

时间:2018-05-18 04:20:35

标签: c c-preprocessor x-macros

考虑以下用户风格的x-macro

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

我们可以使用它以前三个素数重复调用传入的宏func。例如:

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

会声明返回空白的函数foo2()foo3()foo5()

到目前为止,这么好。现在让我们说我想在x-macro本身的定义中使用一个宏作为参数,如下所示:

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

它不起作用,因为MAKE_FUNC现在会尝试声明void fooMAX_PRIME(),因为(我猜)标记连接发生时不会展开MAX_PRIME

我可以解决此问题,以便它像以前一样声明foo5()吗?

2 个答案:

答案 0 :(得分:2)

您可以插入另一个级别的宏扩展(df[paste0('A_', seq(10, 90, 10))] <- lapply(seq(10, 90, 10), function(i) (df$A * i + df$B * (100 - i)) / 100) # > df # A B A_10 A_20 A_30 A_40 A_50 A_60 A_70 A_80 A_90 # 1 0.80 0.9000 0.89000 0.88000 0.87000 0.86000 0.8500 0.84000 0.83000 0.82000 0.81000 # 2 0.99 0.8800 0.89100 0.90200 0.91300 0.92400 0.9350 0.94600 0.95700 0.96800 0.97900 # 3 0.70 0.9658 0.93922 0.91264 0.88606 0.85948 0.8329 0.80632 0.77974 0.75316 0.72658 # 4 0.65 0.6684 0.66656 0.66472 0.66288 0.66104 0.6592 0.65736 0.65552 0.65368 0.65184 )。

PRIMES_X2

使用#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) 输出:

gcc -E

答案 1 :(得分:1)

Yunnosch的答案很好,但是为了进一步旋转X宏的疯狂,你也可以在列表中使用宏调用,而不是在它之外的包装宏。这样做的好处是你可以将“变量”从列表传递给被调用的宏。

我想这可能有一些用处 - 假设您希望使用X宏来声明不同类型的函数?

示例:

#define MAX_PRIME 5

#define CREATE_FUNC(func, ret_type, param) func(ret_type, param)

#define PRIMES_X(func)                 \
  CREATE_FUNC(func, int,    2)         \
  CREATE_FUNC(func, void,   3)         \
  CREATE_FUNC(func, double, MAX_PRIME) \

#define MAKE_FUNC(ret_type, num) ret_type foo ## num(void);
  PRIMES_X(MAKE_FUNC)
#undef MAKE_FUNC

调试代码以检查函数是否确实获得了预期的原型:

int main(void)
{
  (void)foo2();
  foo3();
  (void)foo5();
}

int foo2 (void){ return 0;}
void foo3 (void){}
double foo5 (void){ return 0.0;}