是否必须在单独的条件下进行“已定义”的宏检查及其调用?

时间:2018-07-18 08:55:15

标签: c++ c-preprocessor

我一直在努力找到一个在SO上涉及此主题的答案,但是这里有些看似无辜的代码在F不是定义的宏时无法编译,

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

根据this section of the GCC manual的问题是,在#if表达式内部,“在表达式的值的实际计算开始之前,表达式中的所有宏都已扩展”,因此这是无效的检查,因为当{我知道{1}}是未定义的,

F

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

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

我发现这很丑陋且不直观,因此我希望在预处理器中有一种更好的方法来执行此类操作。

1 个答案:

答案 0 :(得分:2)

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

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

或另一个合理的默认值。这是解决您问题的常用解决方案。另一个是不允许这样的宏 未定义,但需要默认值或期望的默认值。后一种方法是 安全一些,例如配置文件,很明显作者确实考虑了宏 选择了一个值(即他不只是忘记定义它)。如果定义在同一文件中,也会更容易。

您的测试将是:

#if F(0, 2, 0)

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

两个忠告:

  • 仅在合理的情况下,谨慎而谨慎地使用宏。特别是C ++提供的功能可以减少对宏的需求。
  • 不要对宏使用单字母名称。请记住,它们是文本的替代品,除了普通的语言语法之外。请改用不言自明的名称(这不仅适用于宏,而且对于它们更相关)。