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

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

本文关键字:于不同 条件下 调用 defined is 检查      更新时间:2023-10-16

在SO上,我很难找到许多涉及这个主题的答案,但这里有一些看起来很无辜的代码,当F不是一个定义的宏时,它无法编译

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

根据GCC手册的这一节,问题是在#if表达式中,"在表达式值的实际计算开始之前,表达式中的所有宏都已展开",因此这是一个无效的检查,因为当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++特别提供了减少对宏的需求的功能
  • 不要对宏使用单字母名称。请记住,它们是文本替换,与正常语言语法不同。请使用不言自明的名称(这不仅适用于宏,而且对于那些更相关的宏(