调试宏与调试变量
Debug macro vs. Debug variable
下面是使用调试变量的示例
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;
}
};
在预处理器中,h只是
#define DEBUG
使用调试变量的好处是该类对全局预处理器头的依赖性减少了一个。宏方法的好处是,在运行时执行的if语句减少了1000000,这对于图形应用程序来说可能是至关重要的,比如说,当每帧每秒都很重要时。什么是更好的方法?
更好的方法是使用预处理器,但不需要新的头文件来定义宏。
您可以在编译时使用-DMACRO_NAME
或-DDEBUG
设置标志。
只要作业是打印调试信息,就必须像Visual Studio那样使用宏(调试/发布构建)。然而,在Qt世界中,有一个类QLoggingCatagory
,您可以在其中启用/禁用日志记录部分。每当消息被注销时,它都会调用函数QLoggingCategory::isDebugEnabled()
,这让我认为这对性能来说不是什么大问题,至少在正常使用时是这样。
也就是说,如果我们将Visual Studio MFC应用程序与Qt应用程序进行比较,MFC应用程序就会快速启动。这至少在一定程度上可以归因于它使用了宏,并且在调试和发布版本中可以很容易地注意到差异,其中宏/调试信息是主要差异。
鉴于所有这些证据,我投票支持在您的情况下使用宏方法以获得最大性能。
首先,宏方式对内存和if测试都有好处(尽管这确实是一个很小的成本)。您有任何特殊的场景可以使用调试变量吗?
为什么不在CPP文件中定义A::Test()?从而可以将全局预处理器报头移动到CPP文件。无论如何,我不认为在头中公开这样的调试细节是个好主意。
另一种选择是,如果你不喜欢有一堆#ifdef DEBUG/#endif行,你可以创建一个宏,在定义的情况下输出它的参数(很像断言宏)。
#ifdef DEBUG
#define PRINT(x) (x)
#else
#define PRINT(x)
#endif
PRINT( std::cout << "something" << std::endl );
代码路径不会比"compiled-away"小多少。但是,如果您愿意执行重构步骤,您可以以更大的可执行文件为代价,使运行时调试版本更便宜。
这个想法是将调试状态作为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
}
- 为自定义打印调试实现传递任何类型的变量
- 在qt创建器中调试时如何访问字符串变量的完整值?
- 附加调试器并以编程方式获取变量地址 Visual Studio
- 在类声明中初始化 const 成员变量时在调试模式下出现异常
- 在 main 之前调试全局变量的赋值
- 调试:运行时检查失败 #2 - 变量"LoggerThread"周围的堆栈已损坏
- C vs 2017设置全局变量 - 程序仅在调试中使用断点
- 在 Visual Studio 2017 C++项目中设置调试/运行环境变量
- GNU 调试器无法从显示中删除变量?
- 调试宏中的字符串变量扩展
- C++变量和调试器之间的值不同
- 当源代码证明调试变量为NULL时,调试变量如何为NULL
- 是否可以在编译时输出 constexpr 变量来调试模板元程序
- C++ 显示字符串变量"<不完整类型>的调试窗口
- 调试器如何仅查看变量的内存地址
- 如何在 arm 平台中调试 c 程序中的全局变量损坏
- 在没有优化的程序上使用gdb进行调试,但在当前上下文中仍然没有局部变量的符号
- 我可以控制调试器窗口中显示的浮点数和双精度变量的位数吗?
- Visual studio调试工具提示-隐藏变量
- 调试宏与调试变量