我会推荐gnu-cpp-manual,它清楚地解释了宏是如何扩展的。
宏参数在被替换为宏体之前完全进行宏扩展,除非它们(宏参数)被字符串化或与其他标记一起粘贴(由直接应用于)。
例如:
如果参数被字符串化或连接,则不会发生 prescan。
#define AFTERX(x) X_ ## x
#define XAFTERX(x) AFTERX(x)
#define TABLESIZE 1024
#define BUFSIZE TABLESIZE
AFTERX(BUFSIZE) => X_BUFSIZE:由于AFTERX是连接参数和前缀,所以它的参数没有展开,剩下BUFSIZE。
XAFTERX(BUFSIZE) => X_1024:XAFTERX不直接做拼接,所以BUFSIZE会先展开。
通常,参数被扫描两次以扩展在其中调用的宏。
--- 编辑---
所以更好的做法是:(代码来自QEMU源)
#ifndef glue
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
#define stringify(s) tostring(s)
#define tostring(s) #s
#endif
glue(x,y) 将连接 x 和 y,两者都已展开。