C语言预定义宏的存放位置及定义主体技术咨询
咱们一个个来拆解你的问题:
预定义宏是编译器还是预处理器定义的?
本质上是预处理器负责定义和处理这些宏。不过现在很多编译器(比如GCC、Clang)都把预处理器集成到自己的流程里了,所以有时候你会听到“编译器提供预定义宏”的说法,但核心工作还是预处理器在做——毕竟宏替换本来就是预处理阶段的核心任务之一。
预定义宏存放在哪里?
你找不到一个专门的源代码文件来存放这些宏,它们是预处理器内置的符号。简单说,预处理器本身的代码里就维护了一个内置的符号表(类似字典),当预处理阶段开始时,这些宏就已经“存在”在这个表里了,不需要从外部文件读取。
如果你想看看当前编译器环境下有哪些预定义宏,可以用命令行工具查:比如GCC用gcc -dM -E - < /dev/null,Clang用clang -dM -E - < /dev/null,执行后会输出所有预定义宏及其值。
预处理器是否维护存储预定义宏的字典?
没错,预处理器在运行时确实会维护一个符号表(就是你说的字典结构),这个表里包含三类内容:
- 内置的预定义宏(比如
__FILE__、__LINE__、__DATE__) - 你自己在代码里用
#define定义的自定义宏 - 编译时通过命令行参数(比如
-DDEBUG或者-DVERSION="1.0")传入的宏
预处理过程中,每次遇到宏引用,就会去这个表里查对应的值,然后完成替换。
__FILE__宏的定义及等价值是谁提供的?
__FILE__是典型的内置预定义宏,它的替换值是当前正在处理的源文件的路径(可能是相对路径或绝对路径,取决于编译时的工作目录和编译器配置)。这个值是预处理器在处理每个源文件时动态生成的——比如当它处理main.c时,就把__FILE__替换成"main.c"(或者完整路径),处理utils.c时就换成"utils.c"。所以严格来说是预处理器提供的,不过因为预处理器和编译器绑定紧密,有时候也会笼统说是编译器提供的。
举个小例子验证一下:
#include <stdio.h> int main() { printf("我在这个文件里:%s\n", __FILE__); return 0; }
编译运行后,输出的就是你编译的这个源文件的路径,这就是预处理器在预处理阶段帮你替换好的。
内容的提问来源于stack exchange,提问作者Nazim

