这是一个预处理宏。
所有这一切都为预处理器的语法,这基本上说,如果宏尚未定义,定义,并包括#ifndef
和#endif
什么它实现阻止文件包含超过之间的所有代码一次,其中可以导致您的代码中的问题。
你的问题:
为什么它好就忘了包括在这种情况下,我们也可以忘记加入的#define HEADER_FILE后卫?
可以忘记它,因为它仍然是合法的C代码没有它。预处理器在编译之前先处理文件,如果没有逻辑说明它为什么不应该在最终的程序中包含指定的代码。这只是一种常见的做法,但并不是必需的。
一个简单的例子可以帮助说明这是如何工作:
你的头文件,header_file.h
我们会说,这包含:
#ifndef HEADER_FILE
#define HEADER_FILE
int two(void){
return 2;
}
#endif
在另一个文件(foo.c
),你可能有:
#include "header_file.h"
void foo() {
int value = two();
printf("foo value=%d\n", value);
}
一旦“预处理”并准备编译,这将转化为:
int two(void){
return 2;
}
void foo() {
int value = two();
printf("foo value=%d\n", value);
}
所有的包括防护装置完成这里是确定是否将#ifndef ...
和#endif
之间的标题内容应代替原来#include
的粘贴。
但是,由于该函数未被声明为extern
或static
,并且实际上是在头文件中实现的,所以如果您尝试在另一个源文件中使用它,则会出现问题,因为函数定义将不包含在内。
你可能不应该在头文件中包含代码,因为include guard只防止多个包含是一个单独的翻译单元。在两个单独的源文件中包含该头文件可能会在链接时导致双重定义错误。 – paxdiablo
嗯,代码守卫内的非静态函数定义。看起来像一个问题。 – chux
这是真的,值得注意。代码防护可以防止在单个事务中包含多个内容,但是当两个不同的对象文件单独编译并随后链接时,不会防止多重包含。在C中为 –