前不久在做dll,用debug版调试没有问题,生成了release版却突然发现结果有出入,百思不得其解,可气release版不能调试。
在网上查找资料后,前辈们首先指出了debug和release版的区别,读了受益匪浅(其中关于编译选项的部分实在无从了解。。。。卑微啊),下面将文章转了贴出来。
转自
http://dev.csdn.net/htmls/17/17068.html
VC下关于debug和release的不同的讨论 zx_sanjin(1.5kg), shanghai
create: 15:39 2002-12-20
modify: 13:56 2003-1-24
mail : zx_sanjin@163.com
qq : 923452
======================================================
在使用VC开发软件的过程中,正当要享受那种兴奋的时候突然发现:release与debug运行结果不一致,甚至出错,而release又不方便调试,真的是当头一棒啊,可是疼归疼,问题总要解决,下面将讲述一下我的几点经验,看看是不是其中之一:
1. 变量。
大家都知道,debug跟release在初始化变量时所做的操作是不同的,debug是将每个字节位都赋成0xcc(注1),而release的赋值近似于随机(我想是直接从内存中分配的,没有初始化过)。这样就明确了,如果你的程序中的某个变量没被初始化就被引用,就很有可能出现异常:用作控制变量将导致流程导向不一致;用作数组下标将会使程序崩溃;更加可能是造成其他变量的不准确而引起其他的错误。所以在声明变量后马上对其初始化一个默认的值是最简单有效的办法,否则项目大了你找都没地方找。代码存在错误在debug方式下可能会忽略而不被察觉到,如debug方式下数组越界也大多不会出错,在release中就暴露出来了,这个找起来就比较难了:( 还是自己多加注意吧
2. 自定义消息的消息参数。
MFC为我们提供了很好的消息机制,更增加了自定义消息,好处我就不用多说了。这也存在debug跟release的问题吗?答案是肯定的。在自定义消息的函数体声明时,时常会看到这样的写法:afx_msg LRESULT OnMessageOwn(); Debug情况下一般不会有任何问题,而当你在Release下且多线程或进程间使用了消息传递时就会导致无效句柄之类的错误。导致这个错误直接原因是消息体的参数没有添加,即应该写成:afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam); (注2)
3. release模式下不出错,但debug模式下报错。
这种情况下大多也是因为代码书写不正确引起的,查看MFC的源码,可以发现好多ASSERT的语句(断言),这个宏只是在debug模式下才有效,那么就清楚了,release版不报错是忽略了错误而不是没有错误,这可能存在很大的隐患,因为是Debug模式下,比较方便调试,好好的检查自己的代码,再此就不多说了。
4. ASSERT, VERIFY, TRACE..........调试宏
这种情况很容易解释。举个例子:请在VC下输入ASSERT然后选中按F12跳到宏定义的地方,这里你就能够发现Debug中ASSERT要执行AfxAssertFailedLine,而Release下的宏定义却为"#define ASSERT(f) ((void)0)"。所以注意在这些调试宏的语句不要用程序相关变量如i++写操作的语句。VERIFY是个例外,"#define VERIFY(f) ((void)(f))",即执行,这里的作用就不多追究了,有兴趣可自己研究:)。
总结:
Debug与Release不同的问题在刚开始编写代码时会经常发生,99%是因为你的代码书写错误而导致的,所以不要动不动就说系统问题或编译器问题,努力找找自己的原因才是根本。我从前就常常遇到这情况,经历过一次次的教训后我就开始注意了,现在我所写过的代码我已经好久没遇到这种问题了。下面是几个避免的方面,即使没有这种问题也应注意一下:
1. 注意变量的初始化,尤其是指针变量,数组变量的初始化(很大的情况下另作考虑了)。
2. 自定义消息及其他声明的标准写法
3. 使用调试宏时使用后最好注释掉
4. 尽量使用try - catch(...)
5. 尽量使用模块,不但表达清楚而且方便调试。
注1:
afc(afc) 网友提供:
debug版初始化成0xcc是因为0xcc在x86下是一条int 3单步中断指令,这样程序如果跑飞了遇到0xcc就会停下来,这和单片机编程时一般将没用的代码空间填入jmp 0000语句是一样地
注2:
不知大家有没有遇到过这种情况,具体原因我也不太清楚,是不是调用时按着默认的参数多分配了WPARAM+LPARAM的空间而破坏了应用程序的内存空间?还请高手来补充。
NightWolf 网友提供:我遇见过,好像是在函数调用的时候参数入栈的问题。因为MFC的消息使用宏写的,所以如果定义了OnMessage()的函数,编译能够通过,但是调用一次后,堆栈指针发生了偏移。然后就。。。
(完) thanks
======================================================
最后我的dll用buf存下变量一个一个查看,发现的确是变量初始化的问题(类里的),不禁感叹网络的伟大和前人的智慧。
关于编译选项的文章:
http://edu.codepub.com/2009/0617/6503.php
分享到:
相关推荐
标题 "C++ protobuf debug release动态库和静态库" 涉及的是Google的Protocol Buffers(简称protobuf)在C++中的应用,特别是如何构建和使用protobuf的动态库和静态库。Protocol Buffers是一种数据序列化协议,允许...
### Debug 和 Release 编译方式的本质区别 #### 一、Debug与Release编译方式概述 在软件开发领域,为了确保程序质量与效率,通常会采用两种不同的编译配置:Debug模式与Release模式。这两种模式各自拥有不同的编译...
总之,虽然Debug和Release版本之间存在着明显的区别,但这些区别主要是通过不同的编译选项实现的。理解这些选项的作用以及它们如何影响程序的行为对于确保程序的质量至关重要。在实际开发过程中,开发者应充分测试这...
Debug 和 Release 是 VC 编译选项中的两个重要概念,它们之间的区别主要体现在编译方式、优化选项和 Runtime Library 等方面。理解这两者的区别对 C++ 开发者来说非常重要,因为它们直接影响着程序的性能、可靠性和...
在软件开发过程中,特别是使用Visual C++(VC++)这类工具时,经常会遇到Debug版本和Release版本的概念。这两个版本虽然都是由同一份源代码构建而成,但它们之间的差异非常显著,这对于确保软件的质量和性能至关重要...
STL(Standard Template Library,标准模板库)是C++编程中的一个重要组成部分,它提供了一组高效、灵活且可重用的容器、迭代器和算法。然而,在开发过程中,程序员经常遇到一个常见问题:STL库在Debug和Release两种...
通过这个过程,你可以在Windows 10环境中,利用VS2015成功编译Tesseract 4.0的Debug和Release版本,并进行C++程序中的OCR集成。这个过程不仅适用于基本的文本识别,还可以进一步扩展到更复杂的文本分析和处理任务。
在编程领域,尤其是C++编程中,Debug和Release是两种常见的构建配置,它们代表了不同的编译和链接选项集合,直接影响着程序的执行效率和调试能力。理解这两者的差异对于软件开发过程至关重要。 首先,Debug版本是专...
本文将详细介绍如何在Visual Studio中配置OpenCV、Halcon和PCL(包括Debug和Release模式),以及如何调整环境变量以确保一切正常工作。 首先,OpenCV是一个开源计算机视觉库,包含了大量的图像处理和计算机视觉算法...
Debug 和 Release 两个版本是 Eclipse CDT 中两个重要的配置选项,它们的配置正确与否直接影响项目的编译、调试和发布。下面,我们将详细介绍 Eclipse CDT Debug 转 Release 版本的配置与注意事项。 一、 Debug ...
在使用Visual Studio进行C++开发时,有时可能会遇到IDE不显示“Debug”和“Release”配置的情况,这对于软件开发过程中的调试和发布是至关重要的。本文将深入探讨这个问题的原因,并提供有效的解决办法。 首先,...
在本压缩包中,我们找到了OpenCV 3.4.0的x86平台编译版本,分为Debug和Release两种配置,分别对应于软件开发的不同阶段。 1. **OpenCV 3.4.0**: 这是OpenCV的一个特定版本,发布于2018年,包含了众多改进和新功能。...
在Visual Studio (VS)开发环境中,开发者经常需要管理和设置不同的构建配置,如Debug和Release模式。这些配置在编译和调试应用程序时具有不同的优化级别和符号信息,它们的输出路径通常默认不同。然而,有时出于特定...
在Visual Studio(VS)中,开发人员通常会遇到两种编译配置:Debug和Release。这两种配置在构建应用程序时具有显著差异,直接影响程序的性能、体积以及调试能力。 **1. Debug和Release编译方式的本质区别** Debug...
开发包同时提供了debug和release两个版本,这对于软件开发过程中的调试和性能优化非常重要。Debug版本在开发阶段用于定位问题,而Release版本则用于最终产品的部署,因为其运行效率更高。 描述中提到了"openssl-...
在本资源中,你获得了针对Windows 10 64位操作系统的Leptonica库的C++编译版本,适用于Visual Studio 2015开发环境,包含了debug和release两种配置。 首先,让我们详细了解一下Leptonica库。Leptonica提供了一系列...
在VS2019X64环境下编译的OpenSceneGraph 3.6.5版本,是这个库的一个最新稳定版,它包含了对64位系统的优化和支持,同时也提供了debug版和release版供开发者选择,以满足不同的调试和性能需求。 1. **VS2019集成开发...
本资源是为Visual Studio 2013用户提供的`curlib`动态库,包含了调试(Debug)和发布(Release)两个版本,这对于软件开发和调试阶段非常重要。 `curlib`,全称CURL (Client URL Library),是由Daniel Stenberg创建...
在这个压缩包中,"dlib19.17编译后msvc1921的release 与debug版lib静态库"指的是为不同编译配置准备的库文件。release版本通常用于优化性能,去除了调试信息,适合部署在生产环境中。而debug版本则保留了调试信息,...
**C++ Protobuf Release** 是一个针对C++编程语言的Google Protocol Buffers(简称Protobuf)编译好的发行版本,它包含了预编译的头文件和库文件,分为调试(debug)和发布(release)两种模式,适用于不同的开发...