C/C++ 代码的预处理器指令 #ifndef
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2812215/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Preprocessor directive #ifndef for C/C++ code
提问by Leif Andersen
In eclipse, whenever I create a new C++ class, or Cheader file, I get the following type of structure. Say I create header file example.h, I get this:
在 Eclipse 中,每当我创建一个新的 C++ 类或C头文件时,我都会得到以下类型的结构。假设我创建了头文件 example.h,我得到了这个:
/*Comments*/
#ifndef EXAMPLE_H_
#define EXAMPLE_H_
/* Place to put all of my definitions etc. */
#endif
I think ifndef is saying that if EXAMPLE_H_ isn't defined, define it, which may be useful depending on what tool you are using to compile and link your project. However, I have two questions:
我认为 ifndef 是说如果没有定义EXAMPLE_H_,请定义它,这可能有用,具体取决于您使用什么工具来编译和链接您的项目。但是,我有两个问题:
Is this fairly common? I don't see it too often. And is it a good idea to use that rubric, or should you just jump right into defining your code.
What is EXAMPLE_H_ exactly? Why not example.h, or just example? Is there anything special about that, or could is just be an artifact of how eclipse prefers to auto-build projects?
这是相当普遍的吗?我不经常看到它。使用该标题是个好主意,还是应该直接跳到定义代码中。
什么是EXAMPLE_H_?为什么不是example.h,或者只是example?有什么特别之处吗,或者可能只是 eclipse 喜欢自动构建项目的工件?
采纳答案by user308405
This is a common construct. The intent is to include the contents of the header file in the translation unit only once, even if the physical header file is included more than once. This can happen, for example, if you include the header directly in your source file, and it's also indirectly included via another header.
这是一个常见的构造。目的是在翻译单元中只包含一次头文件的内容,即使物理头文件被包含多次。例如,如果您将标头直接包含在源文件中,并且它也通过另一个标头间接包含,则可能会发生这种情况。
Putting the #ifndef wrapper around the contents means the compiler only parses the header's contents once, and avoids redefinition errors.
将#ifndef 包装器放在内容周围意味着编译器只解析头的内容一次,并避免重新定义错误。
Some compilers allow "#pragma once" to do the same thing, but the #ifndef construct works everywhere.
一些编译器允许“#pragma once”做同样的事情,但#ifndef 结构在任何地方都有效。
回答by user308405
Is it common? Yes - allC and C++ header files should be structured like this. EXAMPLE_H is a header guard, it prevents the code in the header being included more than once in the same translation unit, which would result in multiple definition errors. The name EXAPMLE_H is chosen to match the name of the header file it is guarding - it needs to be unique in your project and maybe globally as well. To try to ensure this, it's normal to prefix or suffix it with your project name:
常见吗?是的 -所有C 和 C++ 头文件都应该像这样构造。EXAMPLE_H 是一个头文件保护,它防止头文件中的代码在同一个翻译单元中被多次包含,这会导致多个定义错误。选择名称 EXAPMLE_H 以匹配它所保护的头文件的名称 - 它需要在您的项目中是唯一的,也可能是全局的。为了确保这一点,使用您的项目名称作为前缀或后缀是正常的:
#define MYPROJ_EXAMPLE_H
for example, if your project is called "myproj". Don't be tempted into thinking that prefixing with underscores will magically make it unique, by the way - names like _EXAMPLE_H_
and __EXAMPLE_H__
are illegal as they are reserved for the language implementation.
例如,如果您的项目名为“myproj”。顺便说一下,不要认为加下划线的前缀会神奇地使它独一无二 - 名称之类的_EXAMPLE_H_
和__EXAMPLE_H__
是非法的,因为它们是为语言实现保留的。
回答by Jeff
This is just a common way to protect your includes - in this way it prevents the code from being included twice. And the identifier used could be anything, it's just convention to do it the way described.
这只是保护包含的常用方法 - 通过这种方式可以防止代码被包含两次。使用的标识符可以是任何东西,按照描述的方式来做这只是惯例。
回答by Jonathan M Davis
Always do this at the top of a header file. It's typically called a header guard or an include guard.
始终在头文件的顶部执行此操作。它通常称为标题保护或包含保护。
What it does is make it so that if a header file would be included multiple times, it will only be included once. If you don't do it, then you'll end up with errors about things being defined multiple times and things like that.
它的作用是使得如果一个头文件被多次包含,它只会被包含一次。如果你不这样做,那么你最终会遇到关于事物被多次定义的错误等等。
The exact define doesn't matter that much, though typically it's some variation on the file name. Basically, you're checking whether the given macro has been defined. If it hasn't, then define it, and continue with including the file. If it has, then you must have included the file previously, and the rest of the file is ignored.
确切的定义并不那么重要,尽管通常它是文件名的一些变化。基本上,您正在检查是否已定义给定的宏。如果没有,则定义它,并继续包含该文件。如果有,则您之前必须包含该文件,并且文件的其余部分将被忽略。
回答by James McNellis
This is an include guard. It guarantees that a header is included no more than once.
这是一个包含守卫。它保证包含的标题不超过一次。
For example, if you were to:
例如,如果您要:
#include "example.h"
#include "example.h"
The first time the header is included, EXAMPLE_H_
would not be defined and the if-block would be entered. EXAMPLE_H_
is then defined by the #define
directive, and the contents of the header are evaluated.
第一次包含标题时,EXAMPLE_H_
将不会定义并输入 if 块。 EXAMPLE_H_
然后由#define
指令定义,并评估标头的内容。
The second time the header is included, EXAMPLE_H_
is already defined, so the if-block is not re-entered.
第二次包含标题时,EXAMPLE_H_
已经定义了,因此不会重新输入 if 块。
This is essential to help ensure that you do not violate the one definition rule. If you define a class in a header that didn't have include guards and included that header twice, you would get compilation errors due to violating the one definition rule (the class would be defined twice).
这对于确保您不违反单一定义规则至关重要。如果您在没有包含保护的头文件中定义一个类并包含该头文件两次,由于违反了一个定义规则(该类将被定义两次),您将得到编译错误。
While the example above is trivial and you can easily see that you include example.h
twice, frequently headers include other headers and it's not so obvious.
虽然上面的例子很简单,你可以很容易地看到你包含了example.h
两次,但标题经常包含其他标题,这并不那么明显。
回答by corsiKa
Consider this
考虑这个
File foo.c:
文件 foo.c:
#include foo.h
#include bar.h
File bar.h
文件 bar.h
#include <iostream>
#include foo.h
Now, when we compile foo.c, we have foo.h in there twice! We definitely don't want this, because all the functions will throw compile errors the second time around.
现在,当我们编译 foo.c 时,我们有两次 foo.h!我们绝对不希望这样,因为所有的函数第二次都会抛出编译错误。
To prevent this, we put the INCLUDE GUARD
at the top. That way, if it's already been included, we define a preprocessor variable to tell us not to include it again.
为了防止这种情况,我们将 放在INCLUDE GUARD
顶部。这样,如果它已经被包含,我们定义一个预处理器变量来告诉我们不要再次包含它。
It's very common (often mandated), and very frustrating if someone doesn't put one in there. You should
be able to simply expect that each .h file has a header guard when you included. Of course, you know what they say when you assume things ("makes an ass of u and me") but that should be something you're expecting to see.
这是很常见的(通常是强制要求的),如果有人不把它放在那里,就会非常令人沮丧。您should
能简单地指望每个.h文件中有,当你包含的头后卫。当然,当你假设事情(“让你和我混为一谈”)时,你知道他们说什么,但这应该是你期望看到的。
回答by Christopher Barber
This is called an include guard
and is indeed a common idiom for C/C++ header files. This allows the header file to be included multiple times without multiply including its contents.
这被称为 aninclude guard
并且确实是 C/C++ 头文件的常见习惯用法。这允许头文件被多次包含而不会多次包含其内容。
The name EXAMPLE_H_
is an arbitrary convention but has to obey naming rules for C preprocessor macros, which excludes names like example.h
. Since C macros are all defined in a single global namespace, it is important that you do not have different header files that use the same name for their include guard. Therefore, it is usually a good idea to include the name of your project or library in the include guard name:
该名称EXAMPLE_H_
是任意约定,但必须遵守 C 预处理器宏的命名规则,不包括example.h
. 由于 C 宏都定义在单个全局命名空间中,因此不要让不同的头文件对其包含保护使用相同的名称,这一点很重要。因此,在包含保护名称中包含您的项目或库的名称通常是一个好主意:
#ifndef __MYPROJECT_EXAMPLE_H__
...