错误和异常程序行为的典型原因是什么只在发布编译模式中表现出来但在调试模式下不会发生?
答案 0 :(得分:30)
很多时候,在C ++的调试模式下,所有变量都是空的初始化,而除非明确说明,否则在发布模式下不会发生同样的变化。
检查是否有任何调试宏和未初始化的变量
您的程序是否使用线程,然后优化也会在发布模式下导致一些问题。
同时检查所有异常,例如与发布模式没有直接关系,但有时我们会忽略一些关键异常,例如VC ++中的mem访问冲突,但至少在Linux,Solaris等其他操作系统中也是如此。理想情况下,您的程序不应该捕获诸如访问NULL指针之类的关键异常。
答案 1 :(得分:19)
常见的陷阱是在ASSERT中使用带副作用的表达式。
答案 2 :(得分:9)
其他差异可能是:
答案 3 :(得分:6)
我曾经被一些错误所困扰,这些错误在Debug版本中很好但在Release版本中崩溃了。有许多根本原因(当然包括那些已经在这个帖子中总结的原因)并且我已经被以下所有因素所困扰:
#ifdef _DEBUG
中的成员变量或成员函数,因此在调试版本中类的大小不同。有时在发布版本中使用#ifndef NDEBUG
#ifdef
碰巧只出现在两个版本之一中#pragma pack
这样的东西没有被重置,那么这可能会导致令人讨厌的问题。使用预编译头和强制包含我多年来积累的一些提示,用于深入了解调试/发布错误:
答案 4 :(得分:3)
是的!,如果你有条件编译,可能会有时间错误(优化的发行代码,非优化的调试代码),内存重用与调试堆。
答案 5 :(得分:3)
它可以,特别是如果你在C领域。
一个原因可能是DEBUG版本可能会添加代码以检查杂散指针并以某种方式保护您的代码不会崩溃(或行为不正确)。如果是这种情况,您应该仔细检查从编译器获得的警告和其他消息。
另一个原因可能是优化(通常用于发布版本,关闭用于调试)。代码和数据布局可能已经过优化,而您的调试程序只是访问未使用的内存,发布版本现在尝试访问保留的内存甚至指向代码!
编辑:我看到其他人提到了它:当然,如果不在DEBUG模式下编译,你可能会有条件地排除整个代码段。如果是这样的话,我希望这真的是调试代码而不是对程序本身的正确性至关重要的东西!答案 6 :(得分:3)
CRT库函数在调试与发布(/ MD vs / MDd)中表现不同。
例如,调试版本通常预填充您传递到指定长度的缓冲区以验证您的声明。示例包括strcpy_s
,StringCchCopy
等。即使字符串提前终止,您的 szDest 也最好 n 字节!
答案 7 :(得分:2)
当然,例如,如果你使用像
这样的结构#if DEBUG
//some code
#endif
答案 8 :(得分:2)
在.NET中,即使您不使用#if DEBUG
之类的条件编译,编译器在发布模式下的优化仍然比在调试模式下更加自由,这可能导致仅释放错误好。
答案 9 :(得分:1)
如果没有更多细节,我会假设“不行”意味着它要么在运行时不编译或抛出某种错误。通过#if DEBUG
语句或标有Conditional
属性的方法检查您是否拥有依赖于编译版本的代码。
答案 10 :(得分:1)
你需要提供更多信息,但是,这是可能的。这取决于您的调试版本。您可能正在进行日志记录或额外检查,但不会将其编译为发行版本。这些仅调试的代码路径可能具有意外的副作用,这些副作用会以奇怪的方式改变状态或影响变量。调试版本通常运行较慢,因此这可能会影响线程并隐藏竞争条件。对于发布编译的直接优化也是如此,尽管不太可能(尽管不太可能)发布编译可能会将某些内容短路作为优化。
答案 11 :(得分:1)
有可能会破坏有效代码的编译器优化,因为它们过于激进。
尝试使用较少的优化功能编译代码。
答案 12 :(得分:1)
如果您有条件编译以使调试代码和发布代码不同,那么这是可能的,并且代码中存在仅在发布模式下使用的错误。
除此之外,这是不可能的。调试代码和发布代码的编译方式有所不同,如果在调试器下运行代码的执行方式不同,但如果这些差异中的任何差异导致性能差异以外的任何问题,则问题一直存在。< / p>
在调试版本中可能没有出现错误(因为时序或内存分配不同),但这并不意味着错误不存在。可能还有其他与调试模式无关的因素会改变代码的时序,导致错误发生或不发生,但这一切都归结为如果代码正确,则不会发生错误在任何情况下。
所以,不,调试版本不正常只是因为你可以运行它而不会出错。如果在发布模式下运行时发生错误,则不是因为发布模式,而是因为错误从一开始就存在。
答案 13 :(得分:1)
在非void函数中,所有执行路径都应以return语句结束。
在调试模式下,如果您忘记使用return语句结束这样的路径,则该函数通常默认返回0.
但是,在发布模式下,您的函数可能会返回垃圾值,这可能会影响程序的运行方式。
答案 14 :(得分:0)
另一个原因可能是数据库调用。 您是否在同一线程中多次保存和更新同一记录, 有时用于更新。 由于先前的create命令仍在处理中,因此更新可能失败或没有按预期方式工作,并且对于更新,db调用找不到任何记录。 这不会在调试中发生,因为调试器确保在着陆之前完成所有待处理的任务。
答案 15 :(得分:0)
我记得前一段时间我们在c / c ++中构建dll和pdb。
我记得这个:
然后希望最好。
我有时会暂时向客户端提供dll的调试版本,以便在处理这些错误时不会阻止生产。
答案 16 :(得分:0)
我刚刚经历过,当我打电话给一个没有恢复寄存器的汇编功能时。以前的值。
在&#34;发布&#34;配置,VS正在使用/ O2编译,它优化了代码的速度。因此,一些局部变量只是映射到CPU寄存器(用于优化),这些变量与上述功能共享,导致严重的内存损坏。
无论如何,看看你是否在代码中的任何地方间接地弄乱了CPU寄存器。
答案 17 :(得分:0)
这是可能的。如果它发生并且没有涉及条件编译,那么你可以非常确定你的程序是错误的,并且只是因为偶然的内存初始化甚至是内存中的布局而在调试模式下工作!