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]。

    

参考链接:

[1] fortran debug模式设置和技巧

[2] fortran调试debug 和release 的用法

[3] debug版运行正常,为啥release运行不正常? debug和release的区别?

[4] 谈debug版本可以正常运行,而在release下运行出错之原因及避免类似情况发生

[5] Win32 Release 和 Win32 Debug有什么不同

 

 

原文地址:https://www.cnblogs.com/panscience/p/4972369.html