我一直在头文件中使用警卫一段时间,我理解为什么使用它们的唯一原因是在编译时启用单个包含此内容(包含防护的头文件)。
我想知道是否有其他原因使用标题保护,为什么它们没有在.c文件中使用?如果保护用于.c文件会发生什么?
答。从以下答复中收集。
通常所有定义都进入.c文件,头文件(.h文件)包含所有声明。包含.c文件不是一个好习惯。
为了在编译特定于翻译单元时仅与一个包含的.c文件可用的声明相关联(因此,如果有两个或更多个库需要链接;即,我们有两个或多个翻译单位);标题保护帮助包括头文件ONLY ONCE。
这是因为预编译器阶段甚至在编译文件以获取对象(.o扩展名)文件之前。预处理器阶段替换整个宏并包含相关数据,这样只允许包含.h文件一次。
答案 0 :(得分:12)
标题保护员所做的不是阻止项目中的多个包含,而只是在单个translation unit中。
例如,假设您有两个标头文件a.h
和b.h
。标头文件b.h
包含a.h
,然后a.h
和b.h
都包含在源文件s.c
中。如果没有标题保护,文件a.h
将被包含两次,这可能会导致错误。如果头文件有标题保护,那么文件a.h
将只包含一次。
您不需要源文件中的标题保护,因为通常您不会将包含在其他文件中。
答案 1 :(得分: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。我下次再打包了
#include example_1.h
我将看到EXAMPLE_1
确实在构建系统中定义
并跳过。
对于这个小例子来说这似乎是一件微不足道的事情,但在包含数百个文件的大型项目中,这确实是一个非常有用的功能。而且由于.c files
没有被其他文件包含,所以它并没有真正意义将它们包含在.c files
下。