Win32 Debug & Release
今天帮汤老师调试程序,他生成的程序不能运行,怀疑子程序之间编译顺序的问题;我试了之后,也出现同样的问题,但是把Win32 Debug 换成Win32 Release却可以运行了。
网上搜索了下,在CVF开发平台下两种编译版本Release 和Debug特点如下:
Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
Debug 和 Release 的真正秘密,在于一组编译选项。下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起 Release 版错误,在此不讨论):
Debug模式:
/MDd /MLd 或 /MTd | 使用 Debug runtime library(调试版本的运行时刻函数库) |
/Od | 关闭优化开关 |
/D "_DEBUG" | 相当于 #define _DEBUG,打开编译调试代码开关(主要针对 assert函数) |
/ZI | 创建 Edit and continue(编辑继续)数据库,这样在调试过 程中如果修改了源代码不需重新编译 |
/GZ | 可以帮助捕获内存错误 |
/Gm | 打开最小化重链接开关,减少链接时间 |
Release模式:
/MD /ML 或 /MT | 使用发布版本的运行时刻函数库 |
/O1 或 /O2 | 优化开关,使程序最小或最快 |
/D "NDEBUG" | 关闭条件编译调试代码开关(即不编译assert函数) |
/GF | 合并重复的字符串,并将字符串常量放到只读内存,防止 被修改 |
实际上,Debug 和 Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。
通常 /GZ 选项会造成 Debug 版出错而 Release 版正常的现象,因为 Release 版中未初始化的变量是随机的,这有可能使指针指向一个有效地址而掩盖了非法访问。
CSDN论坛也指出:“一个为调试版本,其中包括了出错时能够定位源代码的在行,如果源文件已经改变,定位出来会有偏移,而且,在这个版本中编译器不会进行代码优化,并且在程序中能用宏定义_DEBUG来确定当前的版本。另一个为正试版本,程序出错只是进行简单的错误处理,编译器会优化代码,以提高性能。”
Release代码更小,执行更快,编译更严格,更慢;当然就没有了调试信息。Debug自动进行变量初始化,而release不进行变量初始化。debug和release还有一个区别,就是编译成的exe,dll,lib文件的size差别很大。
另外还有Release出错,Debug运行正常的情况,例如CSDN论坛提到的:“一个通讯程序,分两块,一个是主程序,一个是一个dll,主程序由多个线程组成,通过loadlibrary调用dll的函数。debug运行正常,经过压力测试也没有什么问题。可是release一跑就飞掉。出错的位置不是太固定,基本上都是释放内存的地方。”
这种情况的解决方案详见参考链接[3,4]。
参考链接:
[2] fortran调试debug 和release 的用法
[3] debug版运行正常,为啥release运行不正常? debug和release的区别?
[4] 谈debug版本可以正常运行,而在release下运行出错之原因及避免类似情况发生
[5] Win32 Release 和 Win32 Debug有什么不同
posted on 2015-11-17 18:33 Paulcnblogs 阅读(1536) 评论(0) 编辑 收藏 举报