为什么不建议在头文件中定义宏?

Why is it not advised to define macros in header files?

Google C++ Style Guide 指南建议不得在 .h(头)文件中定义宏。这样做的缺点是什么?

预处理器按顺序将所有包含的源文件连接在一起。如果您不取消定义宏,它可以应用于首次定义后的任何来源。

由于 header 通常是库的 public API,您在 header 中定义的任何宏都可能最终出现在其他人的代码中,这样做意想不到的事情。

因为意想不到的事情是好的软件的对立面,你应该:

  1. 不使用宏(地道的 C++ 真的不应该)
  2. 在私有范围内定义它们(总是喜欢私有)或
  3. 使用后立即取消定义它们(尽管这会使它们对您自己的代码基本上无用)

最佳解决方案取决于您的用例。包括守卫和其他简单、安全的定义通常被排除在外(function-like 宏更有可能导致问题,但你仍然可以做一些愚蠢的事情,比如 define TRUE FALSE)。

您还可以研究有条件地定义宏,以便它们出现在您的代码中但不会成为 public API 的一部分。在构建期间检查变量集或将宏保存在单独的 header 中允许其他人有选择地、明确地和有意地包含它们,如果宏有助于避免大量样板文件,这会很方便。

出于与 using 语句不应出现在 header 文件中相同的原因:命名空间污染。如果您想在 header 文件中使用宏,请确保在 header 末尾取消定义它们,这样它们就不会被错误地包含。如果您只想在 header 中定义它们并在 cpp 文件中使用它们,请确保 "macros.h" 永远不会包含在任何 header.

这是谁的意思是,您正在开发的 public API 的最终用户可能不希望或不期望,例如,sum(a, b) 扩展到 (一)+(乙)。找到自己宏错误的根源可能是一场噩梦,找到别人几乎是不可能的。