您好,登錄后才能下訂單哦!
本篇內容主要講解“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模式的區別有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。