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