9

我正在研究其他人构建的 C++ 程序,并且看到了很多这样的 DEBUG 用法

#ifdef DEBUG
    cout << "Value is "<< value << endl;
#endif

我自己仍在学习成为一名富裕的 C++ 程序员,我主要使用 Visual Studio 和断点进行调试。所以我想知道,如果我能够通过代码来调试值,还有其他理由使用这些宏吗?

尝试谷歌但没有找到太多有用的页面。

谢谢。

4

7 回答 7

10

有时您不想单步执行整个代码,而只是检查终端中的输出。

如果代码是使用定义编译的DEBUG,可能在调试版本中,您会看到输出。对于发布版本,您不需要。如果你去project settings -> Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions,你会看到它DEBUG是为调试构建定义的,但它不是为发布而定义的。(我其实有_DEBUG

想象一下,你有一个巨大的函数,而你感兴趣的是第 1000 行(这是旧代码,无法更改)。您宁愿单步执行所有那些凌乱的遗留代码,还是在关键点使用有用的调试语句?您是希望控制台告诉您哪里出了问题,还是return在失败位置的 237 个语句中的每一个处设置断点?

于 2012-05-31T21:25:51.930 回答
6

在调试时,通常的做法是在屏幕上转储一些中间值。可视化调试器并不总是有帮助,因为您浪费了大量时间来使用鼠标进行操作。

对“文本模式调试”和日志记录的需求也经常来自嵌入式系统体验,您没有太多视觉帮助,您所能做的就是将一两个字节转储到串行端口或类似的东西。当您习惯于快速找到关键调试点时,您只需在其中插入一些打印代码,其值会检查程序的正确性。

“DEBUG”宏由 MSVC++ 编译器定义,而您的项目在调试模式下编译。当您制作发布版本时,所有对最终用户实际上无用的代码都会被预处理器“剥离”。

典型片段

#ifdef DEBUG
Some code
#endif

如果未定义 DEBUG,则由预处理器删除。

于 2012-05-31T21:26:57.527 回答
3

使用控制台输出而不是调试器来识别多线程错误会很方便。通过断点中断程序流通常会阻止错误的发生,因为它会阻止线程互相踩踏。其他基于时间的错误也是如此。

于 2012-05-31T21:30:39.293 回答
2

“我主要使用 Visual Studio 和断点进行调试”
通过逐步观察代码的行为来调试代码是非常困难的,在某些情况下甚至是不可能的。有时创建这种“调试输出”会更容易,这样您就可以从这些日志中看到正在发生的事情,而不是尝试实时单步执行。

检查是否DEBUG定义了符号是为了确保您的发布版本不会产生这种输出。请注意,Visual Studio 定义_DEBUG了调试配置。更具体地说:“编译器定义_DEBUG您何时指定 /MTd 或 /MDd 选项。这些选项指定 C 运行时库的调试版本。” 还有一个NDEBUG在定义时禁用 C 风格的断言。有关更多信息,请查看_DEBUG 与 NDEBUG

于 2012-05-31T21:28:36.073 回答
1

它用于调试,通过将代码包装在预处理器命令中,您可以打开或关闭该代码。

看看这里:C++ 注释:预处理器

于 2012-05-31T21:26:00.393 回答
1

很容易,当您想获得一些可能帮助您进行“软”调试的消息时,您只需定义 DEBUG 和之间的句子,#ifdef DEBUG并且#endif将生效,并在您的情况下获得一些有用的消息。

这样,当您完成开发并想要发布时,您只需取消定义调试,消息将不再出现。

您可能认为是的,这是一个好主意,但是应用程序的代码更多,但好处是这些是宏并且在编译时进行评估,因此,如果您删除所有这些,应用程序将是相同的: )

于 2012-05-31T21:28:35.950 回答
0

我建议不要使用DEBUG宏。相反,使用标准NDEBUG宏,它是在不需要调试代码时定义的,而不是在需要调试代码时定义的。也就是说,默认情况下启用调试代码。您会发现只有一小部分性能关键代码需要关闭调试检查才能获得足够的性能。

于 2012-06-07T11:31:28.867 回答