#include标头保护格式?

Rob*_*Rob 20 c++ header c-preprocessor

我知道这对项目没有什么影响,但是,假设您使用#defined标头保护C++代码,您使用什么格式?例如假设一个标题foo.hpp:

#ifndef __FOO_HPP__
...

#ifndef INCLUDED_FOO_HPP
...

#ifndef SOME_OTHER_FORMAT
Run Code Online (Sandbox Code Playgroud)

我卖的是关于大写#defines的想法,但不能解决这些守卫的格式.

Fio*_*onn 20

我总是在include guard中包含命名空间或相对路径,因为只有头名称才被证明是危险的.

例如,您有一些大型项目,其中包含代码中的两个文件

/myproject/module1/misc.h
/myproject/module2/misc.h
Run Code Online (Sandbox Code Playgroud)

因此,如果您为包含保护使用一致的命名方案,则可能最终会_MISC_HPP__在两个文件中定义(非常有趣,以找到此类错误).

所以我安顿下来

MYPROJECT_MODULE1_MISC_H_
MYPROJECT_MODULE2_MISC_H_
Run Code Online (Sandbox Code Playgroud)

这些名称相当长,但与双重定义的痛苦相比,这是值得的.

另一种选择,如果你不需要编译器/平台独立性,你可能会寻找一些#pragma once stuff.


MrZ*_*bra 14

我总是用 INCLUDED_FOO_HPP

我不会使用双下划线,因为保留了双下划线.


Mar*_*ote 13

为了真正避免名称冲突,我使用GUID:

#ifndef GUARD_8D419A5B_4AC2_4C34_B16E_2E5199F262ED
Run Code Online (Sandbox Code Playgroud)

  • 不太可能我的系统将包含与已知宇宙中的原子一样多的包含文件 - 除非我们有亚原子硬盘驱动器. (2认同)

Joh*_*itb 10

就个人而言,我只使用文件名FOO_HPP.Google使用整个路径,如SRC_ENGINE_FAST_HPP.

某些名称和函数签名集始终保留给实现:

  • 每个包含双下划线(_ _)或以下划线后跟大写字母(2.11)开头的名称都保留给实现以供任何使用.
  • 以下划线开头的每个名称都保留给实现,以用作全局名称空间中的名称.

(17.4.3.1.2/1)


efo*_*nis 5

我更喜欢这种格式:

#ifndef FOO_HPP
#define FOO_HPP

/* ... */

#endif // FOO_HPP
Run Code Online (Sandbox Code Playgroud)
  • 一个简单的#ifndef而不是#if !define(...),因为使用复杂的条件作为标头防护几乎没有意义。
  • _HPP部分将标识符标记为标头保护
  • 没有前导下划线,因为此类标识符(以 2 个下划线开头或以 1 个下划线和大写字母开头)是为实现而保留的。
  • 基础部分只是文件名FOO。但是,对于要重用的库代码,建议在开始时添加另一部分。这通常是包含名称空间或“模块”名称,例如MYLIB_FOO_HPP,它有助于避免命名冲突。