令牌粘合宏的组成

时间:2014-03-12 14:55:22

标签: c c-preprocessor

我有这些宏

#define NEXT(of_) ((of_ ## _SUFFIX) + 1)
#define AA_SUFFIX (1)
#define BB_SUFFIX (NEXT(AA))  // expands to ((((1)) + 1))
#define CC_SUFFIX (NEXT(BB))  // expands to ((((NEXT(AA))) + 1)) !!!

我希望CC_SUFFIX扩展为3,但它没有(见上文)。 在这种情况下,有没有办法让预处理器评估NEXT(AA)?

1 个答案:

答案 0 :(得分:1)

根据this回答,预处理器“[...]以递归方式扩展其他宏的替换文本(宏本身在这些递归调用中被阻止。)”

考虑到这一点,CC_SUFFIX的扩展最终成为((((NEXT(AA))) + 1))是有意义的,因为宏NEXT(of_)已经使用过一次。要确认这是原因,您可以创建一个与NEXT(of_)完全相同的新宏,并在BB_SUFFIX中使用它:

#define NEXT(of_) ((of_ ## _SUFFIX) + 1)
#define NEXT1(of_) ((of_ ## _SUFFIX) + 1)
#define AA_SUFFIX (1)
#define BB_SUFFIX (NEXT1(AA))
#define CC_SUFFIX (NEXT(BB))

int main(void){
  BB_SUFFIX;
  CC_SUFFIX;
}

运行gcc -E macros.c输出为:

# 1 "/home/jfacorro/dev/macros-expand.c"
# 1 "<command-line>"
# 1 "/home/jfacorro/dev/macros-expand.c"
int main(void){
  ((((1)) + 1));
  (((((((1)) + 1))) + 1));
}

作为旁注,没有必要将宏的表达式包装在括号中,如果丢失它们,扩展会读得更清晰。

#define NEXT(of_) of_ ## _SUFFIX + 1
#define NEXT1(of_) of_ ## _SUFFIX + 1
#define AA_SUFFIX 1
#define BB_SUFFIX NEXT1(AA)
#define CC_SUFFIX NEXT(BB)

产生输出:

int main(void){
  1 + 1;
  1 + 1 + 1;
}