【发布时间】:2011-01-03 13:31:12
【问题描述】:
为什么每个 .h 文件都以 #ifndef #define #endif 开头?我们当然可以在没有这些指令的情况下编译程序。
【问题讨论】:
-
谷歌“包括警卫”
标签: c++ c c-preprocessor include-guards
为什么每个 .h 文件都以 #ifndef #define #endif 开头?我们当然可以在没有这些指令的情况下编译程序。
【问题讨论】:
标签: c++ c c-preprocessor include-guards
这是一个所谓的“包含守卫”。目的是为了防止文件被多次包含时必须被多次解析。
【讨论】:
它可以防止单个文件的多个包含。同样可以使用
#pragma once
指令,但那些 #ifndef 是标准的,因此每个编译器都支持。
【讨论】:
它被称为包含保护。您可以不使用它们进行编写,直到您开始编写大型程序并发现需要从 .c 文件中直接或间接地多次包含同一个 .h 文件。然后,如果没有包含保护,您将得到多个定义错误,但使用它们,头文件内容仅解析一次并跳过所有后续时间,避免这些错误。始终使用它们是一个好习惯。
【讨论】:
如果我理解正确,您想知道在没有包含保护的情况下,是否多次包含头文件会导致错误或危险行为。这是在排除多个定义等之后。
想象一个恶意程序员,其头文件没有包含保护。他的头文件定义了一个宏,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 多次成为#included,其行为取决于在包含assert.h 时是否定义了NDEBUG。所以,assert.h 不能包含守卫。不过,这是一项功能,而不是错误。
【讨论】:
如果头文件包含类似的定义
int i;在没有保护的情况下被多次包含,将产生编译错误。
#pragma once代替
ifndef's。
【讨论】: