溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Debug模式和Release模式的區(qū)別有哪些

發(fā)布時間:2021-10-19 11:29:46 來源:億速云 閱讀:144 作者:iii 欄目:web開發(fā)

本篇內(nèi)容主要講解“Debug模式和Release模式的區(qū)別有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Debug模式和Release模式的區(qū)別有哪些”吧!

用C/C++的朋友都知道編譯器編譯有各種優(yōu)化級別,編譯器優(yōu)化級別大體如下:

O0(默認選項):不開啟優(yōu)化,方便功能調(diào)試

Og:方便調(diào)試的優(yōu)化選項(比O1更保守)

O1:保守的優(yōu)化選項,打開了四十多個優(yōu)化選項

O2:常用的發(fā)布優(yōu)化選項,在O1的基礎上額外打開了四十多個優(yōu)化選項,包括自動內(nèi)聯(lián)等規(guī)則

Os:產(chǎn)生較小代碼體積的優(yōu)化選項(比O2更保守)

O3:較為激進的優(yōu)化選項(對錯誤編碼容忍度最低),在O2的基礎上額外打開了十多個優(yōu)化選項

Ofast:打開可導致不符合IEEE浮點數(shù)等標準的性能優(yōu)化選項。

具體介紹如下:

O0:編譯器默認就是O0,該選項下不會開啟優(yōu)化,方便開發(fā)者調(diào)試。

O1:致力于在不需要過多的編譯時間情況下,盡量減少代碼大小和盡量提高程序運行速度,它開啟了下面的優(yōu)化標志:

-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:如果是為了調(diào)試,該選項是比O0更好的選擇,它會打開O1大部分優(yōu)化標志,但是不會啟用那些影響調(diào)試的標志:

-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級別,該選項下幾乎執(zhí)行了所有支持的優(yōu)化選項,它增加了編譯時間,提高了程序的運行速度,又額外打開了以下優(yōu)化標志:

-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優(yōu)化標志,除了那些經(jīng)常會增加代碼大小的優(yōu)化標志:

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

它還啟用了-finline-functions優(yōu)化標志,使編譯器根據(jù)代碼大小而不是程序運行速度進行優(yōu)化,為了減少代碼大小。

O3:在O2的基礎上又打開了以下優(yōu)化標志

-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的優(yōu)化基礎上,它又開啟了一些可能導致不符合IEEE浮點數(shù)等標準的性能優(yōu)化選項,如-  fast-math, -fallow-store-data-races等。

tips:上述優(yōu)化選項如果想要了解具體含義可以看https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html  官方文檔。

編譯器有這么多優(yōu)化級別,Debug版本和Release版本其實就是優(yōu)化級別的區(qū)別,Debug稱為調(diào)試版本,編譯的結果通常包含有調(diào)試信息,沒有做任何優(yōu)化,方便開發(fā)人員進行調(diào)試,Release稱為發(fā)布版本,不會攜帶調(diào)試信息,同時編譯器對代碼進行了很多優(yōu)化,使代碼更小,速度更快,發(fā)布給用戶使用,給用戶使用以更好的體驗。但Release模式編譯比Debug模式花的時間也會更多。

Debug模式下在內(nèi)存分配上有所區(qū)別,在我們申請內(nèi)存時,Debug模式會多申請一部分空間,分布在內(nèi)存塊的前后,用于存放調(diào)試信息。

對于未初始化的變量,Debug模式下會默認對其進行初始化,而Release模式則不會,所以就有個常見的問題,局部變量未初始化時,Debug模式和Release模式表現(xiàn)有所不同。

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字節(jié)為單位分配內(nèi)存,例如當申請24字節(jié)內(nèi)存時,Release模式下是正常的分配24字節(jié),Debug模式會分配32字節(jié),多了8字節(jié),所以有些數(shù)組越界問題在Debug模式下可以安全運行,Release模式下就會出問題。

Debug模式下可以使用assert,運行過程中有異?,F(xiàn)象會及時crash,Release模式下模式下不會編譯assert,遇到不期望的情況不會及時crash,稀里糊涂繼續(xù)運行,到后期可能會產(chǎn)生奇奇怪怪的錯誤,不易調(diào)試,殊不知其實在很早之前就出現(xiàn)了問題。編譯器在Debug模式下定義_DEBUG宏,Release模式下定義NDEBUG宏,預處理器就是根據(jù)對應宏來判斷是否開啟assert的。

數(shù)據(jù)溢出問題,在一個函數(shù)中,存在某些從未被使用的變量,且函數(shù)內(nèi)存在數(shù)據(jù)溢出問題,在Debug模式下可能不會產(chǎn)生問題,因為不會對該變量進行優(yōu)化,它在棧空間中還是占有幾個字節(jié),但是Release模式下可能會出問題,Release模式下可能會優(yōu)化掉此變量,??臻g相應變小,數(shù)據(jù)溢出就會導致棧內(nèi)存損壞,有可能會產(chǎn)生奇奇怪怪的錯誤。

例如:

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

到此,相信大家對“Debug模式和Release模式的區(qū)別有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關內(nèi)容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI