类函数宏和变量
Posted
技术标签:
【中文标题】类函数宏和变量【英文标题】:function-like macros and variables 【发布时间】:2020-06-08 06:23:25 【问题描述】:出于某种难以理解的原因,在我的代码中我有类似的内容:
#define pippo(x) printf("%d",x)
...
... many lines down in the code
...
int pippo = 0;
相同的标识符pippo
已用于类似函数的宏和变量名!除了这可能在糟糕的维护者中引起的混乱之外,我想知道这是否符合标准。
C99 和 C11(在 6.10.3 中)都说:
10 [...] 类似函数的宏名称的每个后续实例后跟一个 ( 因为下一个预处理标记引入了 预处理被替换列表替换的令牌 定义 [...]
他们没有说明如果类似函数的宏名称 not 后跟一个 '(' 会发生什么,我担心某些编译器可能会认为这是一个错误(或者可能只是发出警告)。
我是不是太担心了?
【问题讨论】:
如果它编译,你为什么担心?但修复肯定更好。 好新词,即:“难以理解!” (我会投票让你成为名誉格拉斯哥人。) @EugeneSh.:即使某些东西可以编译,也会有人担心,因为存在不会阻止编译的错误,而且某些东西可能在一个编译器中编译,而不是在另一个编译器中编译。 【参考方案1】:类函数宏的名称实例不被(
替换。
因此使用名称并不违反 C 标准中的约束。该标准甚至给出了使用这种行为的示例。 C 2018 7.1.4 1,讨论标准库函数及其作为类函数宏的潜在实现(除了作为函数的定义),说:
... 函数的任何宏定义都可以通过将函数的名称括在括号中来在本地抑制,因为名称后面没有表示宏函数名称扩展的左括号。出于同样的句法原因,即使库函数也被定义为宏,也允许获取库函数的地址……
编译器可能会发出警告(尽管当宏名称是上述 C 标准所建议的库函数时,它可能希望抑制此警告),但 GCC 9.2 和 Clang 11.0.0 都不会,即使使用启用所有警告。
【讨论】:
【参考方案2】:5.1.1.2,第 4 点,指定如何“调用”预处理器:
预处理指令被执行,宏调用被扩展,并且 _Pragma 一元运算符表达式被执行。 [...] 然后删除所有预处理指令。
因此这意味着预处理器未触及的任何内容都将被单独保留,包括任何pippo
后面没有(
。
【讨论】:
以上是关于类函数宏和变量的主要内容,如果未能解决你的问题,请参考以下文章