標籤:
程式運行時出現問題,選擇的是Release,win64位的模式,並且已經看到了宏定義NDEBUG,但是程式依然進入上面的部分
解決方案是將屬性->C/C++->代碼產生器->運行庫裡面的多線程調試(/MTD)修改為多線程DLL(/MD)即可
修改之後:
編譯一下
解釋原因來自 http://blog.csdn.net/u013829933/article/details/50321355,感謝~~
這裡總結下他們的區別,後面的那個‘d‘是代表DEBUG版本,沒有‘d‘的就是RELEASE版本了。
首先說/MT
/MT是 "multithread, static version ” 意思是多線程靜態版本,定義了它後,編譯器把LIBCMT.lib 安置到OBJ檔案中,讓連結器使用LIBCMT.lib 處理外部符號。
/MD是 "multithread- and DLL-specific version” ,意思是多線程DLL版本,定義了它後,編譯器把 MSVCRT.lib 安置到OBJ檔案中,它串連到DLL的方式是靜態連結,實際上工作的庫是MSVCR80.DLL。
即:
靜態執行階段程式庫:LIBCMT.lib
動態執行階段程式庫:MSVCRT.lib + MSVCR80.DLL
所以,當你用CMAKE產生工程檔案時,若CMAKE是用/MT產生的(查看工程原始目錄的CMakeLists.txt),則它所調用的執行階段程式庫為:LIBCMT.lib,若產生的工程的執行階段程式庫(Runtime Library)你選擇/MD,則此工程在編譯後連結的時候,將會調用動態執行階段程式庫:MSVCRT.lib + MSVCR80.DLL,明顯,兩次對同一個某執行階段程式庫裡的函數調用的庫不同,則會出現重定義的錯誤。若此工程產生的是庫檔案,則其他工程調用此庫時也必須是/MT。
===============================================
VC項目屬性→配置屬性→C/C++→代碼產生→執行階段程式庫 可以採用的方式有:多線程(/MT)、多線程調試(/MTd)、多線程DLL(/MD)、多線程調試DLL(/MDd)、單線程(/ML)、單線程調試(/MLd)。
Reusable Library Switch Library Macro(s) Defined
| Single Threaded |
/ML |
LIBC |
(none) |
| Static MultiThread |
/MT |
LIBCMT |
_MT |
| Dynamic Link (DLL) |
/MD |
MSVCRT |
_MT and _DLL |
| Debug Single Threaded |
/MLd |
LIBCD |
_DEBUG |
| Debug Static MultiThread |
/MTd |
LIBCMTD |
_DEBUG and _MT |
| Debug Dynamic Link (DLL) |
/MDd |
MSVCRTD |
_DEBUG, _MT, and _DLL |
其中以小寫“d”結尾的選項表示的DEBUG版本的,沒有“d”的為RELEASE版本。大型項目中必須要求所有組件和第三方庫的執行階段程式庫是統一的,否則將會出現LNK2005井噴。
單線程執行階段程式庫選項/ML和/MLd在VS2003以後就被廢了。
/MT和/MTd表示採用多線程CRT庫的靜態lib版本。該選項會在編譯時間將執行階段程式庫以靜態lib的形式完全嵌入。該選項產生的可執行檔運行時不需要執行階段程式庫dll的參加,會獲得輕微的效能提升,但最終產生的二進位代碼因鏈入龐大的執行階段程式庫實現而變得非常臃腫。當某項目以靜態連結庫的形式嵌入到多重專案,則可能造成執行階段程式庫的記憶體管理有多份,最終將導致致命的“Invalid Address specified to RtlValidateHeap”問題。另外託管C++和CLI中不再支援/MT和/MTd選項。
/MD和/MDd表示採用多線程CRT庫的動態dll版本,會使應用程式使用執行階段程式庫特定版本的多線程DLL。連結時將按照傳統VC連結dll的方式將執行階段程式庫MSVCRxx.DLL的匯入庫MSVCRT.lib連結,在運行時要求安裝了相應版本的VC執行階段程式庫可轉散發元件包(當然把這些執行階段程式庫dll放在應用程式目錄下也是可以的)。 因/MD和/MDd方式不會將執行階段程式庫連結到可執行檔內部,可有效減少可執行檔尺寸。當多項目以MD方式運作時,其內部會採用同一個堆,記憶體管理將被簡化,跨模組記憶體管理問題也能得到緩解。
結論:/MD和/MDd將是潮流所趨,/ML和/MLd方式請及時放棄,/MT和/MTd在非必要時最好也不要採用了。
VS運行時 /MD、/MDd 和 /MT、/MTd之間的區別