如何编写仅在DEBUG #defined时编译的'if'条件?

时间:2010-06-23 16:59:25

标签: c++ macros

我需要一些帮助来编写'if-condition'的宏,它只在#define指令定义DEBUG标志时编译。

这是一个说明我想要的例子。第一段代码显示了使用#ifdef编写if条件的常用方法。

#ifdef DEBUG
if( rv == false )
{
     string errorStr = "error in return value" ;
     cout << errorStr << endl ;
     throw( Exception(errorStr) ) ;
}

我想以类似下面的方式编写它:

DEBUG_IF( rv==false )
{
     same code as above
}

这似乎很简单,但我无法定义可以执行此操作的宏。如果有人以前经历过此,请帮助。

感谢。

7 个答案:

答案 0 :(得分:9)

尝试:

#ifdef DEBUG
  #define DEBUG_IF(x) if(x)
#else
  #define DEBUG_IF(x) if(false)
#endif

现在这不会与你现在的完全相同,因为在使用这个方法时,if块内的代码仍然会被编译,尽管它永远不会未定义DEBUG运行,可能会进行优化。相比之下,使用您的原始示例,代码将被预处理器消除,甚至永远不会被编译。

答案 1 :(得分:2)

我认为这就是你要找的东西:

#include <iostream>

#ifdef DEBUG
#define DEBUG_IF(cond) if(cond)
#else
#define DEBUG_IF(cond) if(false)
#endif

int main(int argc, char** argv)
{
  DEBUG_IF(argc > 1)
  {
     std::cout << "In debug mode and at least one argument given" << std::endl;
  }
  else
  {
    std::cout << "Not in debug mode or no arguments given" << std::endl;
  }
}

在命令行中运行此命令,有或没有参数,无论是否使用-DDEBUG进行编译,都可以证明它是按预期工作的。

答案 2 :(得分:1)

恕我直言,最好的方法是

#ifdef DEBUG
if(blah){
    dostuff();
}
#endif

答案 3 :(得分:0)

您希望if是有条件的,以便在Release中无条件地运行代码吗? (正如标题所暗示的那样。)或者您是否希望整个区块都是有条件的? (所以它发布没有阻止。)你在等价代码中错过了#endif,所以无法分辨。

对于前者,你可以使用它:

#ifdef DEBUG
    #define DEBUG_IF(x) if (x)
#else
    #define DEBUG_IF(x) if (false)
#endif

块中的代码将被编译,但由编译器丢弃,因为它是死代码。如果您只想更改条件,请执行以下操作:

#ifdef DEBUG
    #define DEBUG_IF(x) if (x)
#else
    #define DEBUG_IF(x)
#endif

没有DEBUG,整个条件就不复存在了。修复您的问题,以明确您想要的内容。

答案 4 :(得分:0)

我个人会选择#ifdef DEBUG路由而不是代码混淆 DEBUG_IF宏方法。最好编写清晰的代码,不要隐藏某些宏背后的代码。

如果你真的想要走宏观路线,我会单独留下if并专注于条件本身,例如。

#ifdef DEBUG
# define DEBUG_CONDITION(x) x
#else
# define DEBUG_CONDITION(x) false
#endif  /* DEBUG */

if (DEBUG_CONDITION(rv == false))
{
   ...
}

这种方法仍然存在一些模糊处理,但恕我直言,它比建议的DEBUG_IF()宏更可接受,因为它保留了C / C ++语法。

我相信大多数(如果不是全部)编译器只会优化非if(false)情况下DEBUG产生的死代码(例如,相当于if(0))。但是,有些编译器可以想象用这种方法发出“死代码”警告以及你所描述的DEBUG_IF()方法。

答案 5 :(得分:0)

我不建议使用DEBUG_IF类型的宏,因为Kelly指出。

DEBUG_IF(x)
{
    // debugging code
}
else
{
    // release code (should be executed for both debug and release)
}

在这里查看逻辑错误?应该始终执行释放代码,除非它是仅发布的代码,但这对于使用DEBUG_IF宏来说是一个相当容易的错误。写出来可能会令人讨厌,但我认为这是最清晰,最不容易混淆的方式。如果您确实使用它,我建议完全避免使用它。

DEBUG_CONDITION宏也是如此。

if (DEBUG_CONDITION(x) )
{
    // debugging code
}
else
{
    // oops, this never gets executed in debug builds
}

与仅调试代码相比,仅发布代码非常罕见,因此这些类型的出现通常是逻辑错误。当我开始使用C ++时,我想简写所有内容,但多年来我已经学会了,特别是与团队合作,通常最好按照预期写出来。努力在逻辑上实现简洁,但是你必须小心不要越过一条线,减少代码进入混淆边界。

调试一个充满DEBUG_IF / DEBUG_CONDITION宏的大型系统的想法让我头疼不已。

答案 6 :(得分:0)

这里有点晚,但我想知道简单地定义一个常量是否比定义一个函数更优雅:

// Use Firebase library to configure APIs
FirebaseApp.configure()


PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber) { (verificationID, error) in
  if let error = error {
    self.showMessagePrompt(error.localizedDescription)
    return
  }
  // Sign in using the verificationID and the code sent to the user
  // ...
}

这不是更容易阅读吗?有什么想法吗?