简体   繁体   English

#ifndef 语法用于在 C++ 中包含守卫

[英]#ifndef syntax for include guards in C++

I'm currently studying for a CS course's final exam and I've run into a minor (maybe major?) issue regarding the syntax of C++ #ifndef.我目前正在为 CS 课程的期末考试学习,我遇到了一个关于 C++ #ifndef 语法的小问题(也许是大问题?)。

I've looked at the syntax for #infndef when using it as an #include guard, and most on the web seem to say:我已经查看了 #infndef 的语法,将它用作 #include 防护,web 上的大多数内容似乎都在说:

#ifndef HEADER_H
#define "header.h"
...
#endif

But my class's tutorial slides show examples as:但是我班的教程幻灯片显示的示例如下:

#ifndef __HEADER_H__
#define "header.h"
...
#endif

I was wondering what (if any) the difference was between the two.我想知道两者之间有什么区别(如果有的话)。 The exam will most likely ask me to write an #include guard, and I know conventional wisdom is to just go with what the prof / tutor says, but if there's a difference during compilation I'd like to know.考试很可能会要求我写一个#include 守卫,而且我知道传统智慧只是 go 与教授/导师所说的一样,但如果在编译过程中存在差异,我想知道。

The usual practice is to do neither, and put the include guard inside the header file, as it reduces repetition.通常的做法是两者都不做,将 include guard放在header 文件中,因为它可以减少重复。 eg:例如:

header.h header.h

#ifndef HEADER_H
#define HEADER_H

// Rest of header file contents go here

#endif

Precisely what you use as the macro name is down to your particular coding standard.确切地说,您使用什么作为宏名称取决于您的特定编码标准。 However, there are various subtle rules in the C and C++ standards that prevent you from using identifiers beginning with underscores, 1 so you should avoid __HEADER_H__ , just to be on the safe side.但是,在 C 和 C++ 标准中有各种微妙的规则阻止您使用以下划线开头的标识符, 1因此您应该避免__HEADER_H__ ,只是为了安全起见。

It's also worth mentioning that you should pick something that's unlikely to clash with anything else in your codebase.还值得一提的是,您应该选择不太可能与您的代码库中的任何其他内容发生冲突的内容。 For example, if you happened to have a variable called HEADER_H elsewhere (unlikely, I realise), then you'd end up with some infuriating errors.例如,如果您碰巧在其他地方有一个名为HEADER_H的变量(我知道这不太可能),那么您最终会遇到一些令人恼火的错误。


1. See eg section 7.1.3 of the C99 standard. 1. 参见 C99 标准的第 7.1.3 节。

Names starting with a double underscore are reserved for the implementation, so I would advise against using __SOMETHING in your include guards.以双下划线开头的名称保留用于实现,因此我建议不要在包含保护中使用__SOMETHING Also, try to chose names that make clashes unlikely.此外,尽量选择不太可能发生冲突的名称。 So it seems your class' tutorials are wrong on at least two counts.所以看起来你班级的教程至少在两个方面是错误的。 See this humorous article for example.例如,请参阅这篇幽默文章

There's no difference if you don't use underscore in variable names anywhere else, it's only a naming convention.如果您不在其他任何地方的变量名中使用下划线,则没有区别,这只是一种命名约定。

You just need to put something unique.你只需要放一些独特的东西。

An argument for putting the include guards in the file that includes the header, rather than in the header itself, is that if the file has already been included the compiler (specifically the preprocessor) doesn't have to open and read the include file again.将 include guard 放在包含 header 的文件中而不是 header 本身的一个论点是,如果该文件已经被包含,则编译器(特别是预处理器)不必再次打开和读取包含文件.

That's a weak argument.这是一个薄弱的论点。 In practice, the time saved is trivial, and the potential for error is large.在实践中,节省的时间微不足道,而且出错的可能性很大。

In your example:在你的例子中:

#ifndef HEADER_H
#include "header.h"
...
#endif

you don't show us the #define HEADER_H .您没有向我们展示#define HEADER_H Is it somewhere in header.h ?它在header.h的某个地方吗? If so, how do you know that the author of header.h chose to use HEADER_H as the name of the include guard macro?如果是这样,您怎么知道header.h的作者选择使用HEADER_H作为 include guard 宏的名称? What if it changes to something else later?如果它稍后更改为其他内容怎么办?

If you decide to put the include guard in the including file, you should define the macro there as well:如果您决定将 include guard 放在包含文件中,您也应该在那里定义宏:

#ifndef HEADER_H
#include "header.h"
#define HEADER_H
#endif

But, as other answers have already said, it's much better to put the guard in the header itself:但是,正如其他答案已经说过的那样,最好将警卫放在 header 本身:

header.h: header.h:

#ifndef HEADER_H
#define HEADER_H
/* contents of header.h */
#endif

and then the include simply has:然后 include 只是有:

#include "header.h"

and has one less piece of information to worry about.并且少了一条需要担心的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM