【问题标题】:What is the scope of a #define?#define 的范围是什么?
【发布时间】:2016-07-06 15:02:28
【问题描述】:

#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的内容是真的被包含了,还是include的守卫真的被实现了?

TLDR:#defines 是否会从一个编译单元延续到下一个编译单元?还是#define 只存在于单个编译单元中?

当我输入此内容时,我相信我正在回答我自己的问题,并且我会陈述我相信的答案。 #defines 被限制为单个编译单元 (.c)。当预处理器从一个编译单元转到下一个编译单元时,它基本上会忘记任何#defines。因此,在我列出的上面的示例中,包含守卫没有发挥作用。我的这种看法正确吗?

【问题讨论】:

标签: c c-preprocessor


【解决方案1】:

source1.c 与 source2.c 分开编译,因此您的定义在 source1 编译时进行处理,然后作为独立操作在 source2 编译时进行处理。

希望这是一个清晰的解释。

【讨论】:

    【解决方案2】:

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

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

    您可以通过使用-E 标志调用gcc 或使用仅在您的特定编译器上进行预处理的任何标志来检查此预处理源。

    【讨论】:

      【解决方案3】:

      是的,你是对的! 文件的编译,就其本身而言,仅仅是一个正在执行的过程。除非明确完成,否则一个进程不能与另一个进程发生干扰。 c 预处理器只是文字替换机制,以愚蠢的方式执行。无论执行什么条件检查,都仅限于预处理器的正在进行的实例,一旦执行(编译)结束,就没有任何东西可以结转。预处理器不会“配置”编译器,它们的范围仅限于“自己的编译”

      【讨论】:

        猜你喜欢
        • 2011-11-11
        • 2020-10-18
        • 2017-04-22
        • 1970-01-01
        • 2023-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多