在调试模式下工作
Working in debugging mode
我是c++调试技术的新手,我正试图更好地理解添加代码只是为了调试的目的。
当我使用这样的语句时:
#ifdef _DEBUG
cout << "Output that should only be used in Debugging Mode." << endl;
#endif
内的cout语句似乎总是在调试模式中运行和退出,我只希望这一行只在调试模式中执行。这就是我认为这些if语句的目的,除非我似乎误解了它的实际目的。
另外,有人能详细说明CONSTRUCTOR_TRACE
和FUNCTION_TRACE
吗?它们的确切用途是什么,我如何正确使用它们?
#ifdef _DEBUG
是编译时(实际上是预处理时)构造,它与您是否在调试器中执行程序无关,而是与定义了_DEBUG
宏这一事实有关。
通常你至少有两组构建选项,一个用于调试(它定义_DEBUG
,禁用几个编译器优化并生成调试符号),一个用于发布(它不定义_DEBUG
,启用所有相关的编译器优化并且可能不生成调试信息,或者在单独的文件中生成它们)。
当你开发你的程序时,你通常会使用调试配置,当构建可执行文件最终部署/在日常使用中实际使用时,你会使用发布配置,它不会包括#ifdef _DEBUG ... #endif
块中包含的代码。一旦在一种配置中生成了可执行文件,它就会保持这种方式,在编译时定义_DEBUG
的事实在可执行文件中"写在石头上"。
话虽这么说,有平台特定的方法来检测是否附加了调试器,但通常情况下最好不要弄乱这些东西——根据是否附加了调试器来改变程序行为可能会违背使用调试器的目的。
附录
好的,让我看看我是否完全理解了。所以如果我按下f5来运行调试构建,这个#ifdef _DEBUG中的任何内容都会被执行,当我按下ctrl+f5以发布模式运行它时,它不会运行#ifdef _DEBUG中的代码,而它为我做了。我想我没有完全明白你想说什么。如果可以的话,你能解释得简单一点吗?我在c++和Visual Studio环境方面没有那么高级。
在我看来,关于c++的构建/调试过程有一些误解。当你按下F5,发生的是:
- 编译器被调用;它根据当前选择的配置的构建设置编译文件并生成可执行文件;1
- 可执行文件正在运行;
- VS调试器附加到新创建的进程2。
当您按Ctrl+F5时,唯一的区别是跳过步骤3;其余部分完全相同。
那么,_DEBUG
什么时候起作用呢?在步骤1中,生成可执行文件(实际上,在步骤1的早期,在预处理阶段);无论是否附加调试器都没有区别——放在#ifdef _DEBUG
块中的指令已经从可执行文件中写入(或排除)了。
这里的关键是F5/Ctrl+F5和调试/释放配置是两个正交设置;您可以构建一个"调试"可执行文件并在没有调试的情况下启动它,也可以构建一个"发布"可执行文件并在调试的情况下启动它(实际上,这通常是为了调试只在优化构建中出现的问题)。将调试器附加到程序上的事实根本不应该改变程序的行为3。
再次强调,在启动/不启动调试器与你是否想要在运行中附加一个调试器有关,在调试/发布配置中构建与可执行文件的实际构建方式有关(调试配置是一个更"调试友好"设置的集合- _DEBUG
定义为启用调试代码,assert
启用,优化禁用,调试符号启用,…)。
指出
- 如果从以前的构建中有一些可重用的输出,则跳过或缩短此步骤-例如,如果源没有更改上次构建的可执行文件,并保留当前配置;
- 实际上,进程是附带调试器创建的;这个可以引起微妙的问题,但在这里不相关;
- 实际上,在某些情况下,调试器确实改变了它的行为,因为进程可以使用
IsDebuggerPresent
检查调试器,但通常您不想这样做,原因如上所述。
我不认为"调试模式"意味着你认为它的作用。_DEBUG
通常在编译调试版本时定义。编译完成后,没有办法进入和退出"调试模式"。你可以在发行版中编译,然后覆盖可执行文件,但这样二进制文件就会成为发行版,这样你就不能进入"调试模式"了。
这与你是否使用调试器连接到应用程序无关,也与你的心态是"调试"还是"运行"无关。编译完成后,可以假设_DEBUG
是永远定义的(如果在调试模式下编译),或者没有定义(否则)——直到重新编译。
请交叉检查并确保在您的发布项目配置中没有定义预处理器_DEBUG。
如果你使用的是Visual studio,你可以在Project Properties ->选择Configuration作为Release,然后在c++ -> Verify the Preprocessor -> Preprocessor Definitions中检查。
#if _DEBUG
上面的#if将检查是否定义了_DEBUG。如果定义了,它将执行下一个语句,如果没有定义,它将跳过下一个语句。
- 自定义内存管理器在发布模式下工作正常,但在调试模式下则不然
- 装饰器模式在 c++ 中的工作原理
- 我的代码在发布模式下不起作用,而在Qt的调试模式下工作
- 模式匹配函数的时间测量无法正常工作
- ifstream读取二进制文件在发行模式下工作,但在调试模式下不使用
- 打开文件的正确模式是什么,以便 seekp() 的工作方式与在默认模式下打开的文件相同
- 为什么在发布模式下无法访问 for 循环,但在调试中它工作正常
- Python在调试模式下以C 工作,但在EXE文件中不工作
- 该代码在调试模式下工作,但在发布模式C 中不起作用
- 当主GUI线程被阻塞时,如何从工作线程创建无模式对话框
- 如何在 QT 框架工作C++中使用变量作为正则表达式模式
- 在发行模式下开放的软崩溃(调试工作正常)
- 在 C++11 中,lambda 队列是否是工作队列的良好设计模式
- 工作线程队列的这种变体是某种模式或通用结构吗?
- 混合模式程序集(C++/CLI项目)在.NET Core上工作吗
- 在QIODevice::Append模式下打开的QFile意外工作.这是一个Qt错误吗
- 模式功能:它是如何工作的
- zmq呼吸机/工作人员/水槽模式与子流程一起不工作
- 在调试器模式下工作,但在最终版本中不起作用.为什么
- ZeroMq PUB/SUB 模式无法正常工作