#ifndef C++中包含保护的语法

jay*_*yli 8 c++ include-guards

我目前正在攻读CS课程的期末考试,而且我遇到了一个关于C++ #ifndef语法的小问题(可能是主要的?).

当我将#infndef用作#include后卫时,我已经查看了#infndef的语法,网上的大多数人都说:

#ifndef HEADER_H
#define "header.h"
...
#endif
Run Code Online (Sandbox Code Playgroud)

但我班级的教程幻灯片显示的例子如下:

#ifndef __HEADER_H__
#define "header.h"
...
#endif
Run Code Online (Sandbox Code Playgroud)

我想知道两者之间的差异(如果有的话).考试很可能会让我写一个#include后卫,而且我知道传统的智慧只是与教授/导师所说的一致,但如果在编译过程中存在差异,我想知道.

Oli*_*rth 17

通常的做法是不要这样做,并将include guard 放在头文件中,因为它减少了重复.例如:

header.h

#ifndef HEADER_H
#define HEADER_H

// Rest of header file contents go here

#endif
Run Code Online (Sandbox Code Playgroud)

准确地说,您使用的宏名称取决于您的特定编码标准.但是,C和C++标准中有各种微妙的规则阻止您使用以下划线开头的标识符,1因此您应该避免__HEADER_H__,只是为了安全起见.

还值得一提的是,你应该选择一些不太可能与你的代码库中的任何其他东西冲突的东西.例如,如果您碰巧有一个HEADER_H在其他地方调用的变量(不太可能,我意识到),那么您最终会遇到一些令人生气的错误.


1.参见例如C99标准的7.1.3节.

  • "每个包含双下划线_ _或以下划线后跟大写字母(2.12)开头的名称保留给实现用于任何用途.每个以下划线开头的名称保留给实现用作名称全局命名空间." n3290 C++中的§17.6.4.3.2 (2认同)

jua*_*nza 5

以双下划线开头的名称是为实现保留的,因此我建议不要使用__SOMETHING包含保护.此外,尝试选择不太可能发生冲突的名称.所以看来你的班级教程至少有两个错误.例如,请参阅此幽默文章.