这不能按预期工作:
#define stringify(x) #x
printf("Error at line " stringify(__LINE__));
这有效:
#define stringify1(x) #x
#define stringify(x) stringify1(x)
printf("Error at line " stringify(__LINE__));
预处理用于扩展此类宏的优先级是什么?
答案 0 :(得分:15)
扩展宏时,只有当这些参数不受字符串化(#
)或令牌粘贴(##
)运算符时,预处理器才会扩展宏的参数 。所以,如果你有这个:
#define stringify(x) #x
stringify(__LINE__)
然后,预处理器不展开__LINE__
,因为它是字符串化运算符的参数。但是,当你这样做时:
#define stringify1(x) #x
#define stringify(x) stringify1(x)
stringify(__LINE__)
然后,在展开stringify
时,预处理器将__LINE__
扩展为当前行号,因为x
不与{的定义中的字符串化或令牌粘贴运算符一起使用{1}}。然后它会扩展stringify
,我们得到了我们想要的东西。
C99标准中的相关语言来自§6.10.3.1/ 1:
在识别出类似函数的宏的调用参数之后,发生参数替换。替换列表中的参数除非前面有
stringify1
或#
预处理标记或后面跟着##
预处理标记(见下文),否则会在包含所有宏后替换为相应的参数其中有所扩大。在被替换之前,每个参数的预处理标记都被完全宏替换,好像它们形成了预处理文件的其余部分;没有其他预处理令牌可供使用。
条款§6.10.3.2和6.10.3.3继续分别定义##
和#
运算符的行为。