#define的范围是什么?
我有一个关于C / C ++ #define范围的问题,我试图打赌理解预处理器。
假设我有一个包含多个源文件和头文件的项目。假设我有一个包含以下内容的头文件:
// header_file.h
#ifndef __HEADER_FILE
#define __HEADER_FILE
#define CONSTANT_1 1
#define CONSTANT_2 2
#endif
然后我们说我有两个按以下顺序编译的源文件:
// source1.c
#include header_file.h
void funct1(void)
{
int var = CONSTANT_1;
}
// source2.c
#include header_file.h
void funct2(void)
{
int var = CONSTANT_2;
}
假设我已经包含了所有其他必要的开销,这段代码应该可以正常编译。但是,我很好奇在编译之间记住了什么#defines。当我编译上面的代码时,是否实际包含了每个#include的内容,还是实际实现了包含保护?
TLDR:#defines是否会从一个编译单元转移到另一个编译单元?或者#define只存在于一个编译单元中吗?
当我输入时,我相信我正在回答我自己的问题,我会说出我相信的答案。 #defines被约束到单个编译单元(.c)。当预处理器从一个编译单元转到下一个编译单元时,它基本上会忘记任何#defines。因此,在我列出的上述示例中,包含警卫不起作用。我的信念是否正确?
答案 0 :(得分:2)
source1.c是与source2.c分开编译的,因此你的定义是在编译时为source1处理的,然后作为一个独立的动作在编译时为source2处理它们。
希望这是一个明确的解释。
答案 1 :(得分:1)
预处理器宏没有这样的“范围”,它们只是定义了一段应该替换代码中的宏的文本。
这意味着编译器永远不会看到字符串CONSTANT_1
和CONSTANT_2
,而是以预处理的形式获取源代码,并将这些宏替换为其扩展(1
和{{1}分别)。
您可以通过使用2
标志调用gcc
或使用您的特定编译器上的预处理标记来检查此预处理源。
答案 2 :(得分:0)
是的,你是对的!! 文件的编译,仅仅是一个正在执行的过程。除非明确做出,否则一个过程不能与另一个进程交互。 c预处理器只是字面替换机制,以愚蠢的方式执行。无论执行何种条件检查,仅限于正在进行的预处理器实例,一旦执行(编译)结束,就不会进行任何结转。预处理器不“配置”编译器,它们的范围有限,直到“他们自己的编译”