C++基础:Debug与Release版本的区别

C++基础:Debug与Release版本的区别,第1张

C++基础:Debug与Release版本的区别,第2张

说到这个问题,先说说VC对调试和发布的定义。
其实Debug和Release只是VC预定义的编译选项。如果我们愿意,我们可以完全颠倒调试和发布的行为。
当然,我们也可以自己定义一套编译选项,然后命名为ABC、def等。当然,作为习惯,我们还是更喜欢用VC已经定义好的名字。
既然Debug和Release只是编译选项的区别,为什么要区分Debug和Release版本呢?
调试和发布,在我看来主要是根据其针对的对象不同来区分的。
Debug通常称为调试版本。在一系列编译选项的配合下,编译后的结果通常包含调试信息,无需任何优化,从而为开发者提供强大的应用调试能力。
而Release通常称为发布版本,是用户使用的。通常,不允许客户在发布版本上进行调试。所以不保存调试信息,同时往往会进行优化,以达到最小的代码和速度。为用户提供方便。
以下仅比较默认调试和发布版本的选项。有关详细的编译选项,请参考MSDN的说明。
我们对比Debug和Release的默认选项设置,筛选出相同的设置。主要区别如下:
编译选项:/od/d " _ Debug "/GM/rt C1/MDD/fo " Debug \ \ "/zi
链接选项:/out:" Logging \ Debug \ optiontest.dll "/incremental
默认发布设置如下:
编译选项:/O2/GL/d " ndebug "/FD/MD/fo " Release \ \ "/zi
链接选项:/out我的项目\ Logging \ Release \ optiontest.dll "/incremental:no
主要区别在于运行时的性能影响。被调试版本的运行时库包含调试信息,并采用一些保护机制来帮助发现错误,因此其性能不如发布版本。编译器提供的运行时库非常稳定,不会造成发布版本错误。但是,运行时库的调试版本加强了对错误的检测,如堆内存分配检查,但将改为报告错误。需要指出的是,如果Debug有错误,发布版本正常,那一定是程序有bug,只是我们还没有发现而已。
ZI

Zi
其次是/Zi选项和/ZI选项。使用/ZI选项,您可以在调试期间修改代码,而无需重新编译。这是调试的好帮手,但是如果用发布版,就变得不可行了。
Od

O2
/O2和/Od选项:Od关闭编译器优化,常用于调试版本。O2选项是创建代码的最快方式,当然是发布版本的最佳选择。
RTCx
option
/RTCx选项,更强,允许编译器插入动态检测代码,帮助你检测程序中的错误。例如,它将局部变量初始化为非零值。包括用0xCC初始化所有自动变量,用0xCD初始化分配内存(即新内存),用0xDD填充释放内存(即删除内存),用0xFD初始化保护内存(调试版在动态分配内存前后增加保护内存,防止越界访问)。这样做的好处是这些值很大,一般不可能作为指针,考试,大提示也很少作为数值。此外,这些值很容易识别,因此在调试版本中发现只会在发布版本中遇到的错误是有益的。
另外,通过函数指针调用函数时,会通过检查堆栈指针来验证函数调用的匹配性(防止原型不匹配)。
当发布版本正常时,使用/RTCx选项将导致调试版本出错。因为发布版本中未初始化的变量是随机的,很可能指针指向了一个有效但错误的地址,从而掩盖了错误。
说了这么多好处,这个编译选项有一个限制:只能在/Od选项下使用。
Gm

INCREMENTAL or NO
编译选项中的Gm和链接选项中的INCREMENTAL只有一个目的,就是加快编译速度。我们经常会遇到这样的问题,只修改了一个头文件,结果所有的动态库都被重新编译了。而这两个选项正是为了解决这个问题。
如果启用了/Gm开关,编译器会将源文件和类定义之间的依赖关系存储在。项目中的idb文件。然后,中的信息。idb文件用于确定源文件是否需要编译,即使源文件已经包含修改的。h文件。
默认情况下,增量开关是打开的。增量链接生成的可执行文件或动态链接库会因为代码和数据的填充而比非增量链接程序大。此外,增量链接文件还包含一个跳转主干来处理函数到新地址的重定位。
MSDN上说得很清楚:为了保证最终发布版本不包含填充或主干,请非增量链接程序。
_DEBUG

NDEBUG
是本节末尾最重要的选项。这些是编译器的预处理器定义。默认情况下,_DEBUG用于调试版本,NDEBUG用于发布版本。他们可以说是重要得无以复加。因为,assert系列的断言只在_DEBUG下生效!
以下内容摘自assert.h文件:
# ifdef n debug
# define assert(_ expression)((void)0)
# else
# ifdef _ _ cplusplus
extern " C " {
# endif
_ Cr TIMP void _ _ cdecl _ wassert(_ _ in _ z const wchar _ t * _ Message,_ _ in _ z const wchar _ C
# ifdef _ _ cplusplus
}
# endif
# define assert(_ Expression)(void)((!!(_ expression))| |(_ assert(_ CRT _ wide(# _ expression),_ CRT _ wide (_ _ file _ _),_ _ line _ _),0))
# endif/* _ DEBUG */

也就是说我们所有发布的版本都不能使用断言机制进行程序调试。
assert的作用我就不用细说了。如果你不知道assert是什么,那你真的要去补了。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » C++基础:Debug与Release版本的区别

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情