VC下关于debug和release的不同的讨论
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
http://www.wangchao.net.cn/bbsdetail_27457.html
分享到:
相关推荐
VC编译选项Debug和Release的区别,以及如何设置,对于C++开发有很大的帮助。
主要用于删除VC编译生成的文件夹debug和release,因为这两个文件夹下的文件太浪费空间了。 利用STL中的queue来存储文件夹名,实现非递归来查找指定的文件夹debug和release。 其实就是找到一个文件夹就加入文件夹队列...
vc++ ide 不显示Debug,Release的原因及解决办法
VC2008_MFC_CRT_DEBUG_RELEASE_amd64版本 BC2008的MFC运行库, CRT运行库, debug和release, amd64版本, 统一打包到一起, 多线程 DLL (/MD) 方式编译的exe 与这个包的文件放在一起, 在任何windows系统下就都可以...
OpenCV3.4.1的合并式函数库 包含Contrib拓展库 适用于VC14和VC15 X64和X86两种编译架构 Debug和Release两种编译模式 总共8种应用于不同编译环境的OpencCV函数库
很不错的介绍,对于编译的调试很有帮助
PCRE8.32版本,包括debug和release版本,编译通过,并且经过验证
当调试VC 程序时,经常出现release 版本或者debug版本运行崩溃的问题,本文给出了一些解决方法……
OpenCV3.4.1的分离式函数库 包含Contrib拓展库 适用于VC14和VC15 X64和X86两种编译架构 Debug和Release两种编译模式 总共8种应用于不同编译环境的OpencCV函数库
基于最新的curl 7.65.2的源码 在xp vc6下编译的dll 文件,含 debug和release双版本。
VC2008_MFC_CRT_DEBUG_RELEASE_amd64版本 BC2008的MFC运行库, CRT运行库, debug和release, amd64版本, 统一打包到一起, 多线程 DLL (/MD) 方式编译的exe 与这个包的文件放在一起, 在任何windows系统下就都可以运行了
VC2008_MFC_CRT_DEBUG_RELEASE_ia64版本 BC2008的MFC运行库, CRT运行库, debug和release, amd64版本, 统一打包到一起, 多线程 DLL (/MD) 方式编译的exe 与这个包的文件放在一起, 在任何windows系统下就都可以运行...
Debug和Release并没有本质的区别,他们只是VC预定义提供的两组编译选项的集合,编译器只是按照预定的选项行动。如果我们愿意,我们完全可以把Debug和Release的行为完全颠倒过来。当然也可以提供其他的模式,例如自己...
解决不想安装vs2008又不得不使用这些文件的无奈场景;Microsoft.VC90.DebugCRT.manifest及相关DLL,Microsoft.VC90.DebugMFC及相关DLL等。
用 VS2015 编译完成的 zlib 动态库/静态库 X x86/x64 X debug/release 也含有 VS2015下编译用的工程文件
VC2010编译的ActiveMQ-CPP 3.9.3相应的DLL和lib(debug/release) activemq-cpp.dll 、activemq-cpp.lib、cppunit_dll.dll、libapr-1.dll、libapriconv-1.dll、libaprutil-1.dll
vc2019编译的所有libssh2的静态库和动态库,包含所有debug版和release的win32和x64版本
vs2008环境dll mfc所需dll debug+release版本
在vc源码中需要输出的地方用OutputDebugString就可以在这个工具中查看啦,绿色,无污染,好用!