预处理宏为何忽略括号中的函数名?该行为是否符合标准?
为什么预处理宏会忽略括号中的函数名?
这个行为完全是C语言标准明确规定的,咱们一步步拆解来理解:
宏调用的识别规则
C预处理阶段在查找宏调用时,有个核心要求:宏名必须是一个独立的标识符,并且后面紧跟左括号(中间可以有空白字符)。如果宏名被括号包裹起来(比如(abs)),那它就不再符合宏调用的识别条件——预处理程序会把这里的abs当作普通标识符,而不是要展开的宏。
结合你的代码实例分析
看你写的这段代码:
#include <stdio.h> #include <stdlib.h> #define abs(x) ((x)) int main(void) { printf("%d\n", abs(-1)); // 输出:-1 printf("%d\n", (abs)(-1)); // 输出:1 return 0; }
- 第一个
abs(-1):完全符合宏调用的格式,预处理阶段会把它展开成((-1)),本质上就是直接返回参数值,所以输出-1。 - 第二个
(abs)(-1):这里的abs被括号括住,预处理程序不会把它当作宏展开。编译器会去查找全局范围内的abs函数——也就是标准库中用来计算绝对值的abs(),所以最终输出-1的绝对值1。
C标准中的明确说明
在C语言标准(比如C17的6.10.3节)里明确规定:宏调用的格式是宏名后跟左括号,宏名必须是一个标识符,且不能被其他符号(比如括号)包裹。当标识符被括号包裹时,它不再被视为宏名,自然不会触发宏替换。
内容的提问来源于stack exchange,提问作者Kami Kaze
相关产品推荐
相关产品推荐

