调试宏与调试变量

时间:2016-01-11 18:35:49

标签: c++ debugging macros

以下是使用调试变量

的示例
class A{
 public:
  A(bool debug):m_debug(debug){};
  ~A(){};

  void Test(){
    for(int i=0;i<1000000;i++){
      // do something

      if(m_debug) print();
    }
  }

  void print(){
    std::cout << "something" << std::endl;
  }


 private:
  bool m_debug;
};

以下是使用调试宏预处理器

的示例
#include "Preprocessor.h"

class A{
 public:
  void Test(){
    for(int i=0;i<1000000;i++){
      // do something

#ifdef DEBUG
        print();
#endif
    }
  }

  void print(){
    std::cout << "something" << std::endl;
  }
};

在Preprocessor.h中只是

#define DEBUG

使用调试变量的好处是类对全局预处理器头的依赖性较小。关于宏方法的好处是,如果在运行时执行语句,则减少1000000,这对于每个fps计数时的图形应用程序来说可能是至关重要的。什么被认为是更好的方法?

5 个答案:

答案 0 :(得分:5)

更好的方法是使用预处理器,但是,没有必要使用新的头文件来定义宏。

您可以使用-DMACRO_NAME-DDEBUG来设置编译时的标记。

答案 1 :(得分:1)

只要作业打印调试信息,先例就是使用像Visual Studio那样的宏(调试/发布版本)。但是在Qt世界中,有一个类QLoggingCatagory,您可以在其中启用/禁用日志记录部分。每次消息被注销时它都会调用函数QLoggingCategory::isDebugEnabled(),这使我认为这对于性能至少在正常使用中来说不是一个主要问题。

如果说我们使用Qt应用程序来构建Visual Studio MFC应用程序,那么MFC应用程序就可以快速点亮。这可能至少部分是因为它使用宏,并且在调试和发布版本中可以很容易地注意到差异,其中宏/调试信息是主要区别。

鉴于所有这些证据,我的投票是针对您的情况下的宏方法以获得最佳性能。

答案 2 :(得分:0)

首先,宏观方式对于内存中的好处和测试(尽管这是非常小的成本)更好。您是否有使用调试变量的特殊方案?

为什么不在CPP文件中定义A :: Test()?因此,全局预处理器头可以移动到CPP文件。无论如何,我不认为在标题中公开这样的调试细节是个好主意。

答案 3 :(得分:0)

另一种选择,如果你不喜欢拥有一堆#ifdef DEBUG / #endif行,你可以创建一个宏,在定义时输出它的参数(很像断言宏)。

#ifdef DEBUG
#define PRINT(x) (x)
#else
#define PRINT(x)
#endif

PRINT( std::cout << "something" << std::endl );

答案 4 :(得分:0)

代码路径没有比&#34;编译掉&#34;更少。但是,如果您愿意执行重构步骤,则可以以更大的可执行文件为代价使运行时调试版本更便宜。

我们的想法是使调试状态成为重构版本Test()的模板参数,以便它可以在每次迭代时打印或不打印调试语句。然后编译器的死代码消除过程将优化掉false传递给模板的情况下的语句,因为模板参数将被视为模板扩展中的编译时常量。

完全优化的版本仍然可以使用条件编译来始终禁用调试输出。

template <bool Debug>
void TestDebug(){
  for(int i=0;i<1000000;i++){
    // do something
    if (Debug) print();
  }
}

void Test(){
#ifdef DEBUG
  if(m_debug) TestDebug<true>();
  else TestDebug<false>();
#else
  TestDebug<false>();
#endif
}