【问题标题】:When not to use include guard in header file?什么时候不在头文件中使用包含保护?
【发布时间】:2011-10-11 05:05:29
【问题描述】:

我们都知道什么时候使用 include 守卫,但是我们什么时候不应该在我们的项目中使用它呢?

最近看到一个混合编译的项目(CUDA + GCC),故意留下一个头文件(CUDA文件)没有include guard。我只是好奇。

【问题讨论】:

  • 我认为使用它总是安全的,而不是寻找没有用处的情况。
  • 对于普通用户库头,总是添加包含保护。您可以通过重复包含无人看管的标题来使用一些不正当的技巧,但作为一个有声望的家庭男人(或妻子),您永远不必这样做。
  • 显示更多关于头文件的细节?我也很好奇。
  • @KerrekSB 请分享你的技巧!
  • @Santropedro:有一些方法可以通过包含一些调用宏的文件来生成代码,您确实希望每次都包含该文件。宏有时称为X-macros,标题为“x-headers”(因为在某些约定中它们的文件名以x_xx_ 开头);另见here。 Boost.Preprocessor 展示了如何将其发挥到极致。

标签: c++ c include-guards


【解决方案1】:

我想到了两种情况:

  1. 当您想要打开/关闭调试功能时(如 assert.h 的工作原理)
  2. 对于 'x-macro' 类型的功能,您有包含文件执行 2 部分问题,例如定义一个枚举,然后定义一个与枚举对应的字符串化名称数组

【讨论】:

    【解决方案2】:

    当您确实希望使用不同的参数多次包含同一个文件时的一种情况。在这种情况下,包含文件将充当一种模板。一个例子是 Dosbox 上的scalers

    【讨论】:

      【解决方案3】:

      在我们的项目中,我们从不使用包含防护。我们正在使用 include antiguard:

      #ifndef _stdafx_h_
      #define _stdafx_h_
      #else
      #error reinclude stdafx.h
      #endif
      

      因为如果您重新包含相同的标头 - 您编写了错误的代码或使用了错误的架构。

      【讨论】:

      • 所以你不能在项目的两个不同文件中#include <vector>
      • 也许你并不真正理解重新包含标题的问题。在两个不同的 .c/.cpp 文件中包含标头不是重新包含。在一个 .cpp 文件中包含两次标头。如果我们在 stdafx.h 中包含 ,我们不需要将它包含在我们的项目标题中。因为头文件不编译,只有.cpp。对于那些不想考虑应用程序架构的人来说,包含守卫是某种万无一失的方法。使用包含保护,我们无法看到应用程序层的真实层次结构,因为相同的标头相互交叉包含。
      • 我理解项目的设计必须不存在循环依赖。除此之外,从逻辑上讲,我确实认为多次包含相同的标题是有意义的。例如,如果我的“application.cpp”定义了一个向量,我应该包括<vector>,即使我还包括我的“algorithms.h”文件,由于某种原因还包括<vector>。一些样式指南,如 Google 的指南,建议您包含您使用的数据类型的所有标题。
      • 如果我想通过分析源代码来找出层级 - 我做不到。如果我想在项目中将 更改为“myvector.h”,我必须搜索所有源代码文件,而不是只更改 stdafx.h 中的一行。如果我想确定预编译的头文件有效使用,我不能。我不喜欢这样的风格指南,抱歉。
      • 与您的风格类似,如果“algorithms.h”被更改并且现在它包含“myvector.h”,应用程序将无法编译,因为“application.cpp”找不到。我认为我们的两种方法都有利有弊。
      【解决方案4】:

      使用包含保护,以便包含文件可以在单个编译单元中多次包含,而不会导致重复声明。

      当文件应该在单个编译单元中多次包含并且不会导致重复声明时,不要使用包含保护。

      【讨论】:

      • 我对所有内容的新通用回复:“当 X 有不良影响时不要使用 X”。 :p
      • -1 因为这句话的字面意思是“当你不应该做的时候不要做。”
      猜你喜欢
      • 2017-03-10
      • 1970-01-01
      • 2012-09-15
      • 1970-01-01
      • 2013-01-20
      • 1970-01-01
      • 2012-12-31
      • 1970-01-01
      • 2020-07-05
      相关资源
      最近更新 更多