#define的范围是什么?

时间:2016-07-06 15:02:28

标签: c c-preprocessor

#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。因此,在我列出的上述示例中,包含警卫不起作用。我的信念是否正确?

3 个答案:

答案 0 :(得分:2)

source1.c是与source2.c分开编译的,因此你的定义是在编译时为source1处理的,然后作为一个独立的动作在编译时为source2处理它们。

希望这是一个明确的解释。

答案 1 :(得分:1)

预处理器宏没有这样的“范围”,它们只是定义了一段应该替换代码中的宏的文本。

这意味着编译器永远不会看到字符串CONSTANT_1CONSTANT_2,而是以预处理的形式获取源代码,并将这些宏替换为其扩展(1和{{1}分别)。

您可以通过使用2标志调用gcc或使用您的特定编译器上的预处理标记来检查此预处理源。

答案 2 :(得分:0)

是的,你是对的!! 文件的编译,仅仅是一个正在执行的过程。除非明确做出,否则一个过程不能与另一个进程交互。 c预处理器只是字面替换机制,以愚蠢的方式执行。无论执行何种条件检查,仅限于正在进行的预处理器实例,一旦执行(编译)结束,就不会进行任何结转。预处理器不“配置”编译器,它们的范围有限,直到“他们自己的编译”

相关问题