4

我在头文件中使用了一段时间的保护,我理解为什么使用它们的唯一原因是在编译时启用单个包含(头文件有考虑中的保护)。

我想知道是否还有其他原因使用标头保护,为什么它们不在 .c 文件中使用,如果保护也用于 .c 文件会发生什么?

答。从下面的回复中收集。

通常,所有定义都进入 .c 文件,头文件(.h 文件)包括所有声明。包含 .c 文件不是一个好习惯。

为了在编译特定于翻译单元的过程中仅关联一个包含在 .c 文件中可用的声明(因此,如果有两个或多个库需要链接;即,我们有两个或更多翻译单位);标头保护有助于仅包含一次标头文件。

发生这种情况是因为预处理器阶段甚至在编译文件以获取对象(.o 扩展名)文件之前。预处理器阶段替换整个宏并包含相关数据,这允许您的 .h 文件仅包含一次。

4

2 回答 2

12

标题守卫所做的不是防止项目中的多个包含,而是仅在单个翻译单元中。

例如,假设您有两个头文件,a.h并且b.h. 头文件b.h包含a.h,然后两者a.hb.h包含在源文件s.c中。如果没有标头保护,文件a.h将被包含两次,这可能会导致错误。如果头文件有头保护,那么该文件a.h只会被包含一次。

您不需要源文件中的标头保护,因为通常您不会它们包含在其他文件中。

于 2014-01-22T07:08:19.767 回答
2

正如您所提到的,标题保护的主要目的是避免重复包含。

考虑以下示例

您的编译单元中有以下头文件

example_1.h
example_2.h (includes example_1.h)

在“C”文件中,您包含'example_1.h'语句'example_2.h'(宏)

'#include example_1.h'将被执行两次。

添加行时

#ifdef EXAMPLE_1
#define EXAMPLE_1


#endif

到 example_1.h,当你第一次遇到 #include example_1.h 时,你告诉你编译系统,定义一个宏(这个宏是你的构建系统的本地宏),这表明我已经包含了 example_1.h。下次我遇到时 #include example_1.h,我会看到它EXAMPLE_1确实在构建系统中定义并跳过。

对于小例子来说这似乎是一件微不足道的事情,但在具有数百个文件的大型项目中,这确实是一个非常有用的功能。而且由于.c files不被其他文件包含,因此将它们包含在.c files.

于 2014-01-22T07:11:11.407 回答