在C和C ++中,为什么每个.h文件通常都包含#ifndef #define #endif指令?

时间:2010-01-10 21:12:48

标签: c++ c c-preprocessor include-guards

为什么每个.h文件都以#ifndef #define #endif开头?我们当然可以在没有这些指令的情况下编译程序。

5 个答案:

答案 0 :(得分:14)

这是一个所谓的“包括守卫”。目的是防止多次包含文件多次解析。

答案 1 :(得分:4)

它可以防止单个文件的多个包含。使用

可以完成同样的事情
#pragma once

指令,但那些#ifndefs是标准的,因此每个编译器都支持。

答案 2 :(得分:3)

它被称为包含守卫。您可以在没有它们的情况下编写,直到您开始编写大型程序并发现您需要从.c文件中直接或间接地多次包含相同的.h文件。然后,在没有包含保护的情况下,您将获得多个定义错误,但是使用它们,头文件内容仅被解析一次并在随后的所有时间跳过,从而避免了这些错误。总是使用它们是一种很好的做法。

答案 3 :(得分:1)

如果我理解正确,您想知道在没有包含警卫的情况下,是否可以多次包含头文件导致错误或危险行为。这是在排除多个定义等之后。

想象一个恶意程序员,其头文件没有包含警戒。他的头文件定义了一个宏SZ,它是一个用于静态分配数组的大小。程序员可以写这样的头文件:

#ifndef SZ
#define SZ 1024
#else
#if SZ == 1024
#undef SZ
#define SZ 128
#else
#error "You can include me no more than two times!"
#endif
#endif

现在,如果您包含头文件一次,则SZ等于1024.如果您包含它两次,SZ将变为128.当然,大多数真实世界的程序员都不是恶意的,并且没有人真正编写如上所述的代码。

请注意,C标准允许assert.h不止一次#includeNDEBUG d,具体取决于在assert.h包含时是否定义了assert.h。所以,{{1}}不能包括警卫。这是一个功能,而不是一个bug。

答案 4 :(得分:-1)

如果头文件包含像

int i;
这样的定义,那么在没有保护的情况下多次包含它将产生编译错误。
ifndef检查是否未定义某些预处理器变量(和它不是,第一次),然后明确定义它,以避免再次被捕获。 在MSVC中,您还可以使用
#pragma once
代替ifndef