宏观扩张的确切步骤是什么?

时间:2011-07-19 05:05:43

标签: c macros

这不能按预期工作:

#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__));  

预处理用于扩展此类宏的优先级是什么?

1 个答案:

答案 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继续分别定义###运算符的行为。