Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C和C++;,为什么每个.h文件通常被#ifndef#define#endif指令包围?_C++_C_C Preprocessor_Include Guards - Fatal编程技术网

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

C++ 在C和C++;,为什么每个.h文件通常被#ifndef#define#endif指令包围?,c++,c,c-preprocessor,include-guards,C++,C,C Preprocessor,Include Guards,为什么每个.h文件都以#ifndef#define#endif开头?我们当然可以在没有这些指令的情况下编译程序。这就是所谓的“include-guard”。这样做的目的是,如果文件被多次包含,则不必对其进行多次解析。它被称为包含保护。在开始编写大型程序并发现需要多次直接或间接地从.c文件中包含相同的.h文件之前,您可以不使用它们进行编写。如果没有include-guard,您将得到多个定义错误,但是使用它们,头文件内容只解析一次,并在随后的所有时间跳过,从而避免了这些错误。始终使用它们是一种很好

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

这就是所谓的“include-guard”。这样做的目的是,如果文件被多次包含,则不必对其进行多次解析。

它被称为包含保护。在开始编写大型程序并发现需要多次直接或间接地从.c文件中包含相同的.h文件之前,您可以不使用它们进行编写。如果没有include-guard,您将得到多个定义错误,但是使用它们,头文件内容只解析一次,并在随后的所有时间跳过,从而避免了这些错误。始终使用它们是一种很好的做法。

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

#pragma once

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

如果头文件包含类似于int i的定义;然后,在没有保护的情况下多次包含会产生编译错误。
ifndef检查是否未定义某个预处理器变量(这是第一次),然后显式定义该变量以避免再次捕获。 int i;
在MSVC中,您也可以使用#pragma一次,而不是
ifndef

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

#pragma once 想象一个恶意的程序员,他的头文件没有包含保护。他的头文件定义了一个宏,
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
\include
d多次使用不同的行为,这取决于
assert.h
包含时是否定义了
NDEBUG
。因此,
assert.h
不能有包含保护。这是一个功能,而不是一个bug。

Google“包含卫士”并防止同一类的多个定义。是否曾经有过“导入指令”,或者这只是我的想象?@AutoCompulated:这就是他多次解析的意思。要担心的事情比重新定义班级还要多;所有这些都是通过“多重解析”封装的。@janneb@GMan:我知道所有这些东西,但我不知道它到底是什么。我知道类、变量等的重新定义,但这很不舒服,但并不危险。你能给我一些危险行为的例子吗?”汤姆:你可能记得从VisualC++中,它是一个特定于COM类型库的供应商扩展。或者从Objective-C/C++.#pragma一次。是一个特定于编译器的扩展…但公平地说,它是一个广泛支持的扩展