概念
Debug通常稱爲調試版本,它包含調試信息,並且不作任何優化,便於程序員調試程序。
Release稱爲發佈版本,它往往是進行了各種優化,使得程序在代碼大小和運行速度上都是最優的,以便用戶很好地使用。
Debug模式下的命令行
其各個命令的含義在VS中C++設置中可以看到。
/GS
/W3
/Zc:wchar_t
/I"F:\MusicProjAddLutSingleImage\MusicEffect\..\header"
/I"F:\MusicProjAddLutSingleImage\MusicEffect\..\header\grender"
/I"F:\MusicProjAddLutSingleImage\MusicEffect\..\src\app"
/I"F:\MusicProjAddLutSingleImage\MusicEffect\..\src\gmath"
/I"F:\MusicProjAddLutSingleImage\MusicEffect\..\src"
/ZI
/Gm
/Od
/sdl
/Fd"F:\MusicProjAddLutSingleImage\MusicEffect\..\temp\MusicEffect\x64\Debug\vc140.pdb"
/Zc:inline
/fp:precise
/D "_MBCS"
/errorReport:prompt
/WX-
/Zc:forScope
/RTC1
/Gd
/MDd
/Fa"F:\MusicProjAddLutSingleImage\MusicEffect\..\temp\MusicEffect\x64\Debug\"
/EHsc
/nologo
/Fo"F:\MusicProjAddLutSingleImage\MusicEffect\..\temp\MusicEffect\x64\Debug\"
/Fp"F:\MusicProjAddLutSingleImage\MusicEffect\..\temp\MusicEffect\x64\Debug\MusicEffect.pch"
Release模式下的命令行
/GS
/GL
/W3
/Gy
/Zc:wchar_t
/Zi
/Gm-
/O2
/sdl
/Fd"F:\MusicProjAddLutSingleImage\MusicEffect\..\temp\MusicEffect\x64\Release\vc140.pdb"
/Zc:inline
/fp:precise
/D "_MBCS"
/errorReport:prompt
/WX-
/Zc:forScope
/Gd
/Oi
/MD
/Fa"F:\MusicProjAddLutSingleImage\MusicEffect\..\temp\MusicEffect\x64\Release\"
/EHsc
/nologo
/Fo"F:\MusicProjAddLutSingleImage\MusicEffect\..\temp\MusicEffect\x64\Release\"
/Fp"F:\MusicProjAddLutSingleImage\MusicEffect\..\temp\MusicEffect\x64\Release\MusicEffect.pch"
兩個命令的不同處
- Release GL
- 全程序優化打開
- Release下/Gy
- 啓用函數級鏈接打開
- Debug下ZI Release下Zi
- ZI 調試信息格式:用於編程並繼續的程序數據庫
- Zi 調試信息格式:程序數據庫
- Debug下GM Release下Gm-
- GM 啓用最小重新生成
- Gm- 不啓用最小重新生成
- Debug下OD Release下O2
- OD 禁用優化
- O2 使速度最大化
- Debug下 RTC1
- RTC1 基本運行時檢查:堆棧幀 未初始化的變量
- Release下Oi
- Oi 啓用內部函數
- Debug下MDd Release下MD
- MDd 運行庫:多線程調試
- MD 運行庫:多線程DLL
例子:初始化變量
debug跟release在初始化變量時所做的操作是不同的。
- debug是將每個字節位都賦成0xcc
- release的賦值近似於隨機
例子: 內存分配方式
DEBUG版和RELEASE版的內存分配方式是不同的。
- 如果你在DEBUG版中申請
ele
爲6*sizeof(DWORD)=24bytes
,實際上分配給你的是32bytes
(debug版以32bytes爲單位)。 - 而在release版,分配給你的就是
24bytes
(r**elease版以8bytes爲單位**)。
所以在debug版中如果你寫ele[6],可能不會有 什麼問題,而在release版中,就有ACCESS VIOLATE。
例子:ASSERT調試宏
一些代碼在Release模式下不會報錯,但在Debug模式下會報錯,這是因爲Debug模式相當於在編譯程序的時候定義了一個宏:#define _DEBUG。在Release模式下定義了一個宏:#define NDEBUG。
比如我們來看assert函數的實現
#undef assert
#ifdef NDEBUG
#define assert(expression) ((void)0)
#else
_ACRTIMP void __cdecl _wassert(
_In_z_ wchar_t const* _Message,
_In_z_ wchar_t const* _File,
_In_ unsigned _Line
);
#define assert(expression) (void)( \
(!!(expression)) || \
(_wassert(_CRT_WIDE(#expression), _CRT_WIDE(__FILE__), (unsigned)(__LINE__)), 0) \
)
#endif
當定義了宏NDEBUG之後,assert函數是不起作用的。
總結
實際上,Debug和 Release 並沒有本質的界限,他們只是一組編譯選項的集合,編譯器只是按照預定的選項行動。