"is defined" 宏检查及其调用必须在不同的条件下进行吗?

Must a "is defined" macro check and its call be in separate conditions?

我在很多关于 SO 的主题中寻找答案,但这里有一些看似无辜的代码,当 F 不是定义的宏时无法编译,

int main() {
#if defined(F) && F(0, 2, 0)
  return 0;
#endif
  return 1;
}

根据 this section of the GCC manual 的问题是 #if 表达式 "all macros in the expression are expanded before actual computation of the expression’s value begins" 内部,所以这是无效检查,因为当 F 未定义时,我明白了,

test.cpp:2:20: error: missing binary operator before token "("
 #if defined(F) && F(0, 2, 0)
                    ^

我的问题:是像这样正确执行此检查的唯一方法吗?

int main() {
#if defined(F)
#if F(0, 2, 0)
  return 0;
#endif
#endif
  return 1;
}

我觉得这很丑陋而且不直观,所以我希望有更好的方法在预处理器中做这些事情。

假设您的 F 宏定义在某个头文件中,您可以将以下代码放在 include 和它的第一次使用之间:

#ifndef F
#define F(a,b,c) 0
#endif

或者另一个合理的默认值。这是您的问题的常见解决方案。另一个是不允许这样的宏 未定义,但需要默认值或任何预期的值。后一种方法是 更安全一点,例如配置文件,因为它清楚地表明作者确实考虑了宏并且有意 选择了一个值(即他不仅仅是忘记定义它)。如果定义在同一个文件中也会更容易。

你的测试将是:

#if F(0, 2, 0)

避免嵌套条件(如果某处需要 #else,这会造成额外的麻烦。

忠告两句:

  • 仅在合理的情况下,谨慎而谨慎地使用宏。特别是 C++ 提供的功能可以减少对宏的需求。
  • 不要为宏使用单字母名称。请记住,它们是文本替换,超出了正常的语言语法。改为使用不言自明的名称(这不仅适用于宏,而且对于那些它甚至更相关)。