7

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

4

5 回答 5

14

这就是所谓的“包含守卫”。目的是防止文件被多次包含时必须被多次解析。

于 2010-01-10T21:14:59.827 回答
4

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

#pragma once

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

于 2010-01-10T21:17:49.617 回答
3

它被称为包含保护。您可以不使用它们进行编写,直到您开始编写大型程序并发现您需要从 .c 文件中直接或间接地多次包含同一个 .h 文件。然后,如果没有包含保护,您将得到多个定义错误,但使用它们,头文件内容仅解析一次并跳过所有后续时间,避免这些错误。始终使用它们是一个好习惯。

于 2010-01-10T21:17:41.730 回答
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.hd#include多次具有不同的行为,具体取决于是否NDEBUG在包含assert.h. 所以,assert.h不能包含守卫。不过,这是一个功能,而不是错误。

于 2010-01-10T21:56:58.797 回答
-1

如果头文件包含定义,如

诠释我;
比,在没有保护的情况下被多次包含,将产生编译错误。
ifndef 检查是否未定义某些预处理器变量(第一次未定义),然后显式定义它以避免再次被捕获。在 MSVC 中,您还可以使用
#pragma 一次
而不是ifndef's。

于 2010-01-10T21:18:47.797 回答