本文转载自微信公众号《程序喵大师》,作者程序喵大师。转载本文请联系程序大师喵公众号。张爱玲曾说:“发展过程是一门玄学。”有时候,程序在Debug模式下运行的很好,一到Release模式就崩溃了。有时,程序在Debug模式下会崩溃,但在Release模式下运行正常。上面的情况可能很多人都遇到过。使用C/C++的朋友都知道编译器编译有各种优化级别。编译器的优化级别大致如下:O0(默认选项):不开启优化,方便功能调试。Og:方便调试的优化选项(比O1更保守)O1:保守的优化选项,启用了40多个优化选项O2:常用的release优化选项,在O1的基础上额外启用了40多个优化选项,包括自动内联等规则Os:GeneratesmallercodeVolumeoptimizationoptions(moreconservativethanO2)O3:Moreaggressiveoptimizationoptions(lowesttoleranceforerrorcoding)在O2的基础上启用了十多个优化选项。Ofast:开启会导致不符合IEEE浮点数等标准的性能优化选项。具体介绍如下:O0:编译器默认为O0,该选项下不会开启优化,方便开发者调试。O1:致力于最小化代码大小和提高程序速度而无需过多的编译时间,它启用以下优化标志:-fdelayed-branch-fdse-fforward-propagate-fguess-branch-probability-fif-conversion-fif-conversion2-finline-调用一次的函数-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-dceftree-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-timeOg:如果是为了调试,这个选项是比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-sraO2:CommonRelease级别,几乎所有支持的优化选项都在该选项下执行,增加编译时间,提高程序运行速度,额外开启如下优化标志:-flra-remat-foptimize-sibling-calls-foptimize-strlen-fpartial-inlining-fpeephole2-freorder-blocks-算法=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-内置调用-dce-ftree-pre-ftree-switch-conversion-ftree-tail-merge-ftree-vrpOs:打开几乎所有的O2优化标志,除了那些经常增加代码大小的标志:-falign-functions-falign-jumps-falign-labels-falign-loops-fprefetch-loop-arrays-freorder-blocks-algorithm=stc它还启用-finline-functions优化标志,使编译器根据代码大小而不是程序运行速度进行优化,以减少代码大小O3:在O2的基础上,开启了以下优化flags-fgcse-after-reload-fipa-cp-clone-floop-interchange-floop-unroll-and-jam-fpeel-loops-fpredictive-commoning-fsplit-循环-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-stridesOfast:一个比较激进的编译选项,它不会严格遵循标准,基于O3的优化,它还启用了一些可能不符合IEEE浮点数等标准的性能优化选项,比如-fast-math,-fallow-store-data-races等。Tips:如果想了解以上优化选项的具体含义,可以参考https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html官方文档。编译器有很多优化级别。Debug版本和Release版本其实就是优化级别的区别。Debug称为调试版本。编译结果通常包含调试信息,不做任何优化,方便开发者调试。释放就叫释放。该版本不携带调试信息。同时,编译器对代码进行了大量优化,使代码更小更快。发布给用户,为用户提供更好的体验。但是在Release模式下编译会比在Debug模式下花费更多的时间。在调试模式下,内存分配有所不同。当我们申请内存的时候,Debug模式会申请一部分空间,分布在内存块前后,用于存放调试信息。对于未初始化的变量,Debug模式默认会初始化,而Release模式不会,所以有个通病。当局部变量未初始化时,Debug模式和Release模式的行为不同。boolfunc(){boolfound;for(inti=0;i
