温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Debug模式和Release模式的区别有哪些

发布时间:2021-10-19 11:29:46 来源:亿速云 阅读:144 作者:iii 栏目:web开发

本篇内容主要讲解“Debug模式和Release模式的区别有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Debug模式和Release模式的区别有哪些”吧!

用C/C++的朋友都知道编译器编译有各种优化级别,编译器优化级别大体如下:

O0(默认选项):不开启优化,方便功能调试

Og:方便调试的优化选项(比O1更保守)

O1:保守的优化选项,打开了四十多个优化选项

O2:常用的发布优化选项,在O1的基础上额外打开了四十多个优化选项,包括自动内联等规则

Os:产生较小代码体积的优化选项(比O2更保守)

O3:较为激进的优化选项(对错误编码容忍度最低),在O2的基础上额外打开了十多个优化选项

Ofast:打开可导致不符合IEEE浮点数等标准的性能优化选项。

具体介绍如下:

O0:编译器默认就是O0,该选项下不会开启优化,方便开发者调试。

O1:致力于在不需要过多的编译时间情况下,尽量减少代码大小和尽量提高程序运行速度,它开启了下面的优化标志:

-fdelayed-branch  -fdse  -fforward-propagate   -fguess-branch-probability   -fif-conversion  -fif-conversion2  -finline-functions-called-once  -fipa-modref  -fipa-profile  -fipa-pure-const  -fipa-reference  -fipa-reference-addressable  -fmerge-constants  -fmove-loop-invariants  -fomit-frame-pointer  -freorder-blocks  -fshrink-wrap  -fshrink-wrap-separate  -fsplit-wide-types  -fssa-backprop  -fssa-phiopt   -ftree-bit-ccp  -ftree-ccp  -ftree-ch  -ftree-coalesce-vars  -ftree-copy-prop  -ftree-dce  ftree-dominator-opts  -ftree-dse  -ftree-forwprop   -ftree-fre  -ftree-phiprop  -ftree-pta  -ftree-scev-cprop  -ftree-sink   -ftree-slsr  -ftree-sra   -ftree-ter  -funit-at-a-time

Og:如果是为了调试,该选项是比O0更好的选择,它会打开O1大部分优化标志,但是不会启用那些影响调试的标志:

-fbranch-count-reg                                          -fdelayed-branch  -fdse  -fif-conversion  -fif-conversion2  -finline-functions-called-once  -fmove-loop-invariants  -fssa-phiopt  -ftree-bit-ccp   -ftree-dse  -ftree-pta   -ftree-sra

O2:常见的Release级别,该选项下几乎执行了所有支持的优化选项,它增加了编译时间,提高了程序的运行速度,又额外打开了以下优化标志:

-flra-remat   -foptimize-sibling-calls   -foptimize-strlen   -fpartial-inlining   -fpeephole2   -freorder-blocks-algorithm=stc   -freorder-blocks-and-partition    -freorder-functions   -frerun-cse-after-loop     -fschedule-insns    -fschedule-insns2 -fsched-interblock    -fsched-spec   -fstore-merging   -fstrict-aliasing   -fthread-jumps   -ftree-builtin-call-dce   -ftree-pre   -ftree-switch-conversion    -ftree-tail-merge   -ftree-vrp

Os:打开了几乎所有的O2优化标志,除了那些经常会增加代码大小的优化标志:

-falign-functions                                                  -falign-jumps  -falign-labels  -falign-loops  -fprefetch-loop-arrays  -freorder-blocks-algorithm=stc

它还启用了-finline-functions优化标志,使编译器根据代码大小而不是程序运行速度进行优化,为了减少代码大小。

O3:在O2的基础上又打开了以下优化标志

-fgcse-after-reload                                           -fipa-cp-clone  -floop-interchange  -floop-unroll-and-jam  -fpeel-loops  -fpredictive-commoning  -fsplit-loops  -fsplit-paths  -ftree-loop-distribution  -ftree-loop-vectorize  -ftree-partial-pre  -ftree-slp-vectorize  -funswitch-loops  -fvect-cost-model  -fvect-cost-model=dynamic  -fversion-loops-for-strides

Ofast:更加激进的编译选项,它不会严格遵循标准,在O3的优化基础上,它又开启了一些可能导致不符合IEEE浮点数等标准的性能优化选项,如-  fast-math, -fallow-store-data-races等。

tips:上述优化选项如果想要了解具体含义可以看https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html  官方文档。

编译器有这么多优化级别,Debug版本和Release版本其实就是优化级别的区别,Debug称为调试版本,编译的结果通常包含有调试信息,没有做任何优化,方便开发人员进行调试,Release称为发布版本,不会携带调试信息,同时编译器对代码进行了很多优化,使代码更小,速度更快,发布给用户使用,给用户使用以更好的体验。但Release模式编译比Debug模式花的时间也会更多。

Debug模式下在内存分配上有所区别,在我们申请内存时,Debug模式会多申请一部分空间,分布在内存块的前后,用于存放调试信息。

对于未初始化的变量,Debug模式下会默认对其进行初始化,而Release模式则不会,所以就有个常见的问题,局部变量未初始化时,Debug模式和Release模式表现有所不同。

bool func() {     bool found;     for (int i = 0; i < vec.size(); ++i) {         if (vec[i] == 3) {             found = true;         }     }     return found;  }

Debug模式下可能运行正常,但Release模式下可能会返回错误结果,因为found局部变量在Release模式下没有初始化。

Debug模式以32字节为单位分配内存,例如当申请24字节内存时,Release模式下是正常的分配24字节,Debug模式会分配32字节,多了8字节,所以有些数组越界问题在Debug模式下可以安全运行,Release模式下就会出问题。

Debug模式下可以使用assert,运行过程中有异常现象会及时crash,Release模式下模式下不会编译assert,遇到不期望的情况不会及时crash,稀里糊涂继续运行,到后期可能会产生奇奇怪怪的错误,不易调试,殊不知其实在很早之前就出现了问题。编译器在Debug模式下定义_DEBUG宏,Release模式下定义NDEBUG宏,预处理器就是根据对应宏来判断是否开启assert的。

数据溢出问题,在一个函数中,存在某些从未被使用的变量,且函数内存在数据溢出问题,在Debug模式下可能不会产生问题,因为不会对该变量进行优化,它在栈空间中还是占有几个字节,但是Release模式下可能会出问题,Release模式下可能会优化掉此变量,栈空间相应变小,数据溢出就会导致栈内存损坏,有可能会产生奇奇怪怪的错误。

例如:

void func() {     char buffer[10];     int counter;     lstrcpy(buffer, "abcdefghik"); // 需要拷贝11字节 }

到此,相信大家对“Debug模式和Release模式的区别有哪些”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI