以下是使用调试变量
的示例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计数时的图形应用程序来说可能是至关重要的。什么被认为是更好的方法?
答案 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
}