青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

C++樂園

C/C++ 交流

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  12 隨筆 :: 18 文章 :: 14 評論 :: 0 Trackbacks
經常在?CSDN?上看見有人問?Debug?運行正常但?Release?失敗的問題。以往的討論往往是經驗性的,并沒有指出會這樣的真正原因是什么,要想找出真正的原因通常要憑運氣。最近我看了一些這方面的書,又參考了?CSDN?上的一些帖子,然后深入研究了一下關于二者的不同。以下是我的一些體會,拿來與大家共享。?--------------------------------------?本文主要包含如下內容:
?1.?Debug?和?Release?編譯方式的本質區別?
2.?哪些情況下?Release?版會出錯?
2.?怎樣"調試"?Release?版的程序?--------------------------------------?
關于Debug和Release之本質區別的討論?一、Debug?和?Release?編譯方式的本質區別?Debug?通常稱為調試版本,它包含調試信息,并且不作任何優化,便于程序員調試程序。Release?稱為發布版本,它往往是進行了各種優化,使得程序在代碼大小和運行速度上都是最優的,以便用戶很好地使用。?Debug?和?Release?的真正秘密,在于一組編譯選項。下面列出了分別針對二者的選項(當然除此之外還有其他一些,如/Fd?/Fo,但區別并不重要,通常他們也不會引起?Release?版錯誤,在此不討論)?Debug?版本:?/MDd?/MLd?或?/MTd?使用?Debug?runtime?library(調試版本的運行時刻函數庫)?/Od?關閉優化開關?/D?"_DEBUG"?相當于?#define?_DEBUG,打開編譯調試代碼開關(主要針對?assert函數)?/ZI?創建?Edit?and?continue(編輯繼續)數據庫,這樣在調試過?程中如果修改了源代碼不需重新編譯?/GZ?可以幫助捕獲內存錯誤?/Gm?打開最小化重鏈接開關,減少鏈接時間?Release?版本:?/MD?/ML?或?/MT?使用發布版本的運行時刻函數庫?/O1?或?/O2?優化開關,使程序最小或最快?/D?"NDEBUG"?關閉條件編譯調試代碼開關(即不編譯assert函數)?/GF?合并重復的字符串,并將字符串常量放到只讀內存,防止?被修改?實際上,Debug?和?Release?并沒有本質的界限,他們只是一組編譯選項的集合,編譯器只是按照預定的選項行動。事實上,我們甚至可以修改這些選項,從而得到優化過的調試版本或是帶跟蹤語句的發布版本。?二、哪些情況下?Release?版會出錯?有了上面的介紹,我們再來逐個對照這些選項看看?Release?版錯誤是怎樣產生的?1.?Runtime?Library:鏈接哪種運行時刻函數庫通常只對程序的性能產生影響。調試版本的?Runtime?Library?包含了調試信息,并采用了一些保護機制以幫助發現錯誤,因此性能不如發布版本。編譯器提供的?Runtime?Library?通常很穩定,不會造成?Release?版錯誤;倒是由于?Debug?的?Runtime?Library?加強了對錯誤的檢測,如堆內存分配,有時會出現?Debug?有錯但?Release?正常的現象。應當指出的是,如果?Debug?有錯,即使?Release?正常,程序肯定是有?Bug?的,只不過可能是?Release?版的某次運行沒有表現出來而已。?2.?優化:這是造成錯誤的主要原因,因為關閉優化時源程序基本上是直接翻譯的,而打開優化后編譯器會作出一系列假設。這類錯誤主要有以下幾種:?(1)?幀指針(Frame?Pointer)省略(簡稱?FPO?):在函數調用過程中,所有調用信息(返回地址、參數)以及自動變量都是放在棧中的。若函數的聲明與實現不同(參數、返回值、調用方式),就會產生錯誤————但?Debug?方式下,棧的訪問通過?EBP?寄存器保存的地址實現,如果沒有發生數組越界之類的錯誤(或是越界"不多"),函數通常能正常執行;Release?方式下,優化會省略?EBP?棧基址指針,這樣通過一個全局指針訪問棧就會造成返回地址錯誤是程序崩潰。C++?的強類型特性能檢查出大多數這樣的錯誤,但如果用了強制類型轉換,就不行了。你可以在?Release?版本中強制加入?/Oy-?編譯選項來關掉幀指針省略,以確定是否此類錯誤。此類錯誤通常有:

?●?MFC?消息響應函數書寫錯誤。正確的應為?afx_msg?LRESULT?OnMessageOwn(WPARAM?wparam,?LPARAM?lparam);?ON_MESSAGE?宏包含強制類型轉換。防止這種錯誤的方法之一是重定義?ON_MESSAGE?宏,把下列代碼加到?stdafx.h?中(在#include?"afxwin.h"之后),函數原形錯誤時編譯會報錯?#undef?ON_MESSAGE?#define?ON_MESSAGE(message,?memberFxn)?\?{?message,?0,?0,?0,?AfxSig_lwl,?\?(AFX_PMSG)(AFX_PMSGW)(static_cast<?LRESULT?(AFX_MSG_CALL?\?CWnd::*)(WPARAM,?LPARAM)?>?(&memberFxn)?},?(2)?volatile?型變量:volatile?告訴編譯器該變量可能被程序之外的未知方式修改(如系統、其他進程和線程)。優化程序為了使程序性能提高,常把一些變量放在寄存器中(類似于?register?關鍵字),而其他進程只能對該變量所在的內存進行修改,而寄存器中的值沒變。如果你的程序是多線程的,或者你發現某個變量的值與預期的不符而你確信已正確的設置了,則很可能遇到這樣的問題。這種錯誤有時會表現為程序在最快優化出錯而最小優化正常。把你認為可疑的變量加上?volatile?試試。?(3)?變量優化:優化程序會根據變量的使用情況優化變量。例如,函數中有一個未被使用的變量,在?Debug?版中它有可能掩蓋一個數組越界,而在?Release?版中,這個變量很可能被優化調,此時數組越界會破壞棧中有用的數據。當然,實際的情況會比這復雜得多。與此有關的錯誤有:

?●?非法訪問,包括數組越界、指針錯誤等。
例如?void?fn(void)?{?int?i;?i?=?1;?int?a[4];?{?int?j;?j?=?1;?}?a[-1]?=?1;//當然錯誤不會這么明顯,例如下標是變量?a[4]?=?1;?}?j?雖然在數組越界時已出了作用域,但其空間并未收回,因而?i?和?j?就會掩蓋越界。而?Release?版由于?i、j?并未其很大作用可能會被優化掉,從而使棧被破壞。?3.?_DEBUG?與?NDEBUG?:當定義了?_DEBUG?時,assert()?函數會被編譯,而?NDEBUG?時不被編譯。除此之外,VC++中還有一系列斷言宏。這包括:?ANSI?C?斷言?void?assert(int?expression?);?C?Runtime?Lib?斷言?_ASSERT(?booleanExpression?);?_ASSERTE(?booleanExpression?);?MFC?斷言?ASSERT(?booleanExpression?);?VERIFY(?booleanExpression?);?ASSERT_VALID(?pObject?);?ASSERT_KINDOF(?classname,?pobject?);?ATL?斷言?ATLASSERT(?booleanExpression?);?此外,TRACE()?宏的編譯也受?_DEBUG?控制。?所有這些斷言都只在?Debug版中才被編譯,而在?Release?版中被忽略。唯一的例外是?VERIFY()?。事實上,這些宏都是調用了?assert()?函數,只不過附加了一些與庫有關的調試代碼。如果你在這些宏中加入了任何程序代碼,而不只是布爾表達式(例如賦值、能改變變量值的函數調用?等),那么?Release?版都不會執行這些操作,從而造成錯誤。初學者很容易犯這類錯誤,查找的方法也很簡單,因為這些宏都已在上面列出,只要利用?VC++?的?Find?in?Files?功能在工程所有文件中找到用這些宏的地方再一一檢查即可。另外,有些高手可能還會加入?#ifdef?_DEBUG?之類的條件編譯,也要注意一下。?順便值得一提的是?VERIFY()?宏,這個宏允許你將程序代碼放在布爾表達式里。這個宏通常用來檢查?Windows?API?的返回值。有些人可能為這個原因而濫用?VERIFY()?,事實上這是危險的,因為?VERIFY()?違反了斷言的思想,不能使程序代碼和調試代碼完全分離,最終可能會帶來很多麻煩。因此,專家們建議盡量少用這個宏。?4.?/GZ?選項:這個選項會做以下這些事?(1)?初始化內存和變量。包括用?0xCC?初始化所有自動變量,0xCD?(?Cleared?Data?)?初始化堆中分配的內存(即動態分配的內存,例如?new?),0xDD?(?Dead?Data?)?填充已被釋放的堆內存(例如?delete?),0xFD(?deFencde?Data?)?初始化受保護的內存(debug?版在動態分配內存的前后加入保護內存以防止越界訪問),其中括號中的詞是微軟建議的助記詞。這樣做的好處是這些值都很大,作為指針是不可能的(而且?32?位系統中指針很少是奇數值,在有些系統中奇數的指針會產生運行時錯誤),作為數值也很少遇到,而且這些值也很容易辨認,因此這很有利于在?Debug?版中發現?Release?版才會遇到的錯誤。要特別注意的是,很多人認為編譯器會用?0?來初始化變量,這是錯誤的(而且這樣很不利于查找錯誤)。?(2)?通過函數指針調用函數時,會通過檢查棧指針驗證函數調用的匹配性。(防止原形不匹配)?(3)?函數返回前檢查棧指針,確認未被修改。(防止越界訪問和原形不匹配,與第二項合在一起可大致模擬幀指針省略?FPO?)?通常?/GZ?選項會造成?Debug?版出錯而?Release?版正常的現象,因為?Release?版中未初始化的變量是隨機的,這有可能使指針指向一個有效地址而掩蓋了非法訪問。?除此之外,/Gm?/GF?等選項造成錯誤的情況比較少,而且他們的效果顯而易見,比較容易發現。?三、怎樣"調試"?Release?版的程序?遇到?Debug?成功但?Release?失敗,顯然是一件很沮喪的事,而且往往無從下手。如果你看了以上的分析,結合錯誤的具體表現,很快找出了錯誤,固然很好。但如果一時找不出,以下給出了一些在這種情況下的策略。?1.?前面已經提過,Debug?和?Release?只是一組編譯選項的差別,實際上并沒有什么定義能區分二者。我們可以修改?Release?版的編譯選項來縮小錯誤范圍。如上所述,可以把?Release?的選項逐個?注:那篇文章到此就完了,好像還有一些沒了。

在VC中當整個工程較大時,軟件時常為出現在DEBUG狀態下能運行而在RELEASE狀態下無法運行的情況。由于開發者通常在DEBUG狀態下開發軟件,所以這種情況時常是在我們辛苦工作一兩個月后,滿懷信心的準備將軟件發行時發生。為了避免無謂的損失,我們最好進行以下的檢查:?1、時常測試軟件的兩種版本。?2、不要輕易將問題歸結為DEBUG/RELEASE問題,除非你已經充分對兩種版本進行了測試。?3、預處理的不同,也有可能引起這樣的問題。出現問題的一種可能性是在不同版本的編譯間定義了不同的預處理標記。請對你的DEBUG版本的軟件試一下以下改動:?在"Project?Setting(ALT-F7)"?中的C/C++項中設置目錄(category)為"General",并且改動"_DEBUG"定義為"NDEBUG".?設置目錄為"Preprocessor"并且添加定義"_DEBUG到"Undefined?Symbols"輸入框.?選擇Rebuild?ALL,重新編譯.?如果經過編譯的程序產生了問題,請對代碼進行如下改動:?將ASSERT()?改為?VERIFY().?找出定義在"#ifdef?_DEBUG"中的代碼,如果在RELEASE版本中需要這些代碼請將他們移到定義外。?查找TRACE(...)中代碼,因為這些代碼在RELEASE中也不被編譯。?所以請認真檢查那些在RELEASE中需要的代碼是否并沒有被便宜。?4、變量的初始化所帶來的不同,在不同的系統,或是在DEBUG/RELEASE版本間都存在這樣的差異,所以請對變量進行初始化。?5、是否在編譯時已經有了警告?請將警告級別設置為3或4,然后保證在編譯時沒有警告出現.?6、是否改動了資源文件.?7、此外對RELEASE版本的軟件也可以進行調試,請做如下改動:?在"Project?Settings"?中?"C++/C?"?項目下設置?"category"?為?"General"?并且將"Debug?Info"設置為?"Program?Database".?在"Link"項目下選中"Generate?Debug?Info"檢查框。?"Rebuild?All"?如此做法會產生的一些限制:?無法獲得在MFC?DLL中的變量的值。?必須對該軟件所使用的所有DLL工程都進行改動。?另:?MS?BUG:MS的一份技術文檔中表明,在VC5中對于DLL的"Maximize?Speed"優化選項并未被完全支持,因此這將會引起內存錯誤并導致程序崩潰。
posted on 2007-02-26 16:57 小不懂^_^ 閱讀(4042) 評論(1)  編輯 收藏 引用

評論

# re: Debug 運行正常但 Release 失敗的問題,Debug 和 Release 編譯方式的本質區別 2015-04-08 16:41 88876
到處都是復制的內容  回復  更多評論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲第一偷拍| 亚洲欧美大片| 亚洲综合欧美| 亚洲线精品一区二区三区八戒| 亚洲春色另类小说| 一区二区三区亚洲| 亚洲成人资源| 亚洲乱码视频| 一区二区三区黄色| 亚洲欧美一区二区在线观看| 欧美夜福利tv在线| 久久手机免费观看| 欧美成人亚洲成人| 国产一区二区三区高清在线观看| 国产亚洲电影| 激情六月婷婷久久| 日韩午夜av电影| 欧美一区二区三区久久精品茉莉花 | 亚洲黑丝一区二区| 亚洲精一区二区三区| 亚洲婷婷综合久久一本伊一区| 在线亚洲成人| 久久精品91久久香蕉加勒比 | 欧美黑人一区二区三区| 亚洲毛片在线观看| 欧美在线播放视频| 欧美激情一区二区三区在线视频观看| 欧美日韩免费观看中文| 娇妻被交换粗又大又硬视频欧美| 亚洲精品一区二区三区樱花| 亚洲欧美在线视频观看| 男女激情久久| 亚洲欧美日本日韩| 欧美精品日韩一区| 精品动漫3d一区二区三区| 亚洲天堂av图片| 尹人成人综合网| 一二三区精品| 欧美亚洲综合在线| 亚洲欧洲一区| 99国产成+人+综合+亚洲欧美| 欧美综合国产精品久久丁香| 欧美精品亚洲精品| 一区二区三区在线视频免费观看 | 精品成人国产| 欧美一级视频精品观看| 嫩草国产精品入口| 亚洲欧美日韩区| 欧美天堂亚洲电影院在线观看| 亚洲国产三级在线| 老司机午夜免费精品视频| 亚洲网友自拍| 欧美日韩精品免费观看视频| 亚洲国产成人不卡| 久久国产精品亚洲va麻豆| aa国产精品| 欧美三区在线视频| 亚洲看片一区| 亚洲国产成人精品女人久久久| 久久精品免费电影| 国产一区二区精品久久91| 亚洲欧美美女| 亚洲字幕一区二区| 免费影视亚洲| 每日更新成人在线视频| 亚洲福利专区| 亚洲大胆人体视频| 六月婷婷一区| 亚洲乱码国产乱码精品精 | 亚洲二区在线| 欧美成人亚洲| 欧美成人精品一区二区| 亚洲精品午夜精品| 亚洲精品中文字幕女同| 欧美日韩1080p| 亚洲一区二区欧美| 亚洲欧美日韩精品久久| 国产一区二区三区黄视频| 久热精品视频在线观看一区| 久久婷婷国产综合精品青草| 亚洲第一色在线| 亚洲国产免费| 欧美日韩一级大片网址| 亚洲自拍高清| 欧美在线中文字幕| 亚洲黄色成人| 妖精视频成人观看www| 国产乱肥老妇国产一区二| 久久福利精品| 乱中年女人伦av一区二区| 亚洲国产精品一区二区第一页| 国产日本欧美一区二区| 午夜性色一区二区三区免费视频| 亚洲一区二区免费看| 国产专区一区| 亚洲二区三区四区| 欧美性片在线观看| 久久香蕉精品| 欧美日韩国产在线播放网站| 午夜精品视频| 美女性感视频久久久| 亚洲免费一级电影| 狂野欧美一区| 欧美亚洲日本网站| 欧美成人精品h版在线观看| 亚洲综合视频一区| 免费中文日韩| 久久99伊人| 欧美日韩国产在线播放网站| 久久综合九九| 国产精品乱人伦中文| 欧美激情二区三区| 国产麻豆精品视频| 亚洲精选国产| 亚洲国产精品第一区二区| 午夜精品视频| 亚洲午夜小视频| 欧美jizz19性欧美| 久久综合九色九九| 国产美女精品免费电影| 91久久精品国产91性色| 亚洲视频在线观看网站| 亚洲人成在线影院| 久久精品91久久久久久再现| 亚洲欧美另类综合偷拍| 欧美高清视频一区二区| 另类酷文…触手系列精品集v1小说| 欧美午夜电影在线观看| 亚洲国产日韩欧美在线图片| 红杏aⅴ成人免费视频| 亚洲伊人观看| 亚洲免费在线视频| 欧美日韩免费高清一区色橹橹| 欧美激情中文字幕乱码免费| 韩日精品视频| 欧美自拍丝袜亚洲| 久久在线免费视频| 国产视频不卡| 欧美一区二区三区电影在线观看| 亚洲一区二区三区精品在线观看 | 亚洲午夜三级在线| 亚洲视频久久| 欧美午夜宅男影院| 一区二区三区欧美亚洲| 一级日韩一区在线观看| 欧美区日韩区| 亚洲免费电影在线观看| 一本色道久久综合亚洲精品婷婷| 欧美交受高潮1| 91久久中文| 夜夜嗨av一区二区三区| 欧美麻豆久久久久久中文| 亚洲电影视频在线| 亚洲乱码国产乱码精品精天堂| 欧美国产欧美亚洲国产日韩mv天天看完整 | 亚洲你懂的在线视频| 一本久久综合| 国产精品国产三级国产aⅴ9色| 亚洲乱码国产乱码精品精可以看| 一区二区三区高清不卡| 欧美性久久久| 亚洲一区二区在线免费观看视频| 亚洲欧美日韩区| 国产一区二区三区成人欧美日韩在线观看| 久久xxxx| 欧美aⅴ99久久黑人专区| 亚洲韩国日本中文字幕| 欧美三级日本三级少妇99| 亚洲欧美日韩一区二区在线| 国产欧美在线观看一区| 久久久精品动漫| 91久久精品日日躁夜夜躁欧美| 亚洲色图综合久久| 国产亚洲精品久久久久动| 另类激情亚洲| 99热在这里有精品免费| 久久精品色图| 99视频精品在线| 国产欧美二区| 欧美成人国产一区二区| 亚洲午夜电影| 欧美岛国在线观看| 亚洲女ⅴideoshd黑人| 激情av一区二区| 欧美四级在线观看| 久久久久成人网| 一区二区毛片| 亚洲国产精品久久久久秋霞不卡 | 欧美va天堂在线| 亚洲一区二区三区精品在线| 亚洲国产精品国自产拍av秋霞| 欧美一区二区三区四区夜夜大片| 亚洲国产成人精品久久久国产成人一区 | 欧美不卡视频一区| 亚洲综合色在线| 亚洲精品综合在线| 欧美电影资源| 久久五月婷婷丁香社区| 亚洲尤物视频在线| 一个色综合导航|