張愛玲曾說過:“開發過程就是個玄學。”
有時候,程序在Debug模式下運行的好好的,一Release就crash了。
有時候,程序在Debug模式下崩潰了,Release模式下居然能正常運行。
以上這種情況,可能很多人都遇到過。

Ofast:打開可導致不符合IEEE浮點數等標準的性能優化選項。
具體介紹如下:
Og:如果是為了調試,該選項是比O0更好的選擇,它會打開O1大部分優化標志,但是不會啟用那些影響調試的標志:
O2:常見的Release級別,該選項下幾乎執行了所有支持的優化選項,它增加了編譯時間,提高了程序的運行速度,又額外打開了以下優化標志:
Os:打開了幾乎所有的O2優化標志,除了那些經常會增加代碼大小的優化標志:
Ofast:更加激進的編譯選項,它不會嚴格遵循標準,在O3的優化基礎上,它又開啟了一些可能導致不符合IEEE浮點數等標準的性能優化選項,如- fast-math, -fallow-store-data-races等。
對于未初始化的變量,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字節}
tips:不要將Debug庫和Release庫混合在一起,可能會出問題,至于為啥會出問題,知道的可在下方評論區留言,一般都是有兩個目錄,Debug目錄和Release目錄。
回到開篇提到的那兩個問題:
程序在Debug模式下運行的好好的,Release模式下就crash了,怎么辦?
可以嘗試著找一找代碼中的assert,看一下是否是assert導致的兩種模式下的差異,從這個思路入手。
程序在Debug模式下會崩潰,Release模式下卻正常運行,怎么辦?
看一下代碼中是否有未初始化的變量,是否有數組越界問題,從這個思路入手。
參考資料:

END
→點關注,不迷路←