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

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 小不懂^_^ 閱讀(4055) 評論(1)  編輯 收藏 引用

評論

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


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲欧美日韩一区二区三区在线观看 | 亚洲在线成人| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ入口 | 女人香蕉久久**毛片精品| 一区二区亚洲精品国产| 欧美jjzz| 欧美日韩另类综合| 欧美一区二区啪啪| 久久不射中文字幕| 亚洲高清成人| 亚洲另类在线视频| 国产精品视频成人| 久久精品欧洲| 男女激情久久| 亚洲一区二区三区四区在线观看 | 91久久精品国产91性色tv| 欧美理论电影在线播放| 午夜精品久久久久久久99樱桃 | 亚洲国内精品在线| 国产精品久久久久久久7电影| 久久99伊人| 美女在线一区二区| 亚洲欧美日韩国产中文| 久久综合久久88| 亚洲综合久久久久| 乱码第一页成人| 午夜精品久久久久久久男人的天堂 | 裸体素人女欧美日韩| 欧美精品videossex性护士| 西西人体一区二区| 欧美刺激性大交免费视频| 午夜精品久久久久久久99热浪潮 | 亚洲天堂av高清| 影音先锋日韩资源| 在线视频免费在线观看一区二区| 国内自拍一区| 亚洲视频在线看| 亚洲国产高清aⅴ视频| 亚洲一级一区| 在线性视频日韩欧美| 久久久777| 久久高清免费观看| 欧美色图五月天| 免费在线亚洲欧美| 国产一区二区三区直播精品电影 | 亚洲精品国产无天堂网2021| 国产一区二区三区四区hd| 99精品视频一区| 亚洲理论在线| 蜜臀va亚洲va欧美va天堂| 久久乐国产精品| 国产乱码精品一区二区三区忘忧草| 亚洲精品国产精品国产自| 在线日韩精品视频| 欧美在线3区| 久久国产精品72免费观看| 国产精品女主播| 99精品视频免费在线观看| 亚洲免费观看在线观看| 欧美福利视频在线观看| 你懂的视频一区二区| 影音先锋另类| 久久人体大胆视频| 米奇777超碰欧美日韩亚洲| 国产一区二区日韩精品欧美精品 | 亚洲欧洲免费视频| 亚洲激情网站| 欧美国产大片| 亚洲精品国产精品久久清纯直播 | 久久一区亚洲| 在线观看欧美一区| 久久综合狠狠综合久久综合88| 久久综合伊人77777蜜臀| 国产在线精品一区二区中文| 久久av资源网站| 老司机久久99久久精品播放免费| 精品999在线播放| 久久亚洲私人国产精品va媚药| 欧美国产欧美亚洲国产日韩mv天天看完整| 激情综合色综合久久| 美女国产一区| 亚洲精品小视频| 香蕉久久a毛片| 伊人久久综合97精品| 欧美freesex交免费视频| 亚洲精品在线电影| 欧美亚洲一区| 在线播放一区| 欧美日韩一区二区三区四区五区| 亚洲图片欧美午夜| 久久女同精品一区二区| 亚洲国产小视频在线观看| 欧美日韩hd| 午夜视频久久久久久| 欧美激情一区二区三区高清视频| 一区二区三区导航| 国产欧美一区二区三区另类精品 | 欧美激情va永久在线播放| 一本色道久久88综合亚洲精品ⅰ | 欧美一区二区视频在线观看2020| 国产一区二区高清视频| 欧美激情国产日韩精品一区18| 一区二区久久久久久| 久久先锋影音| 亚洲网站在线| 在线免费观看一区二区三区| 欧美日韩一区二区三区免费看| 久久成人国产| 亚洲精品在线观看免费| 久热精品视频在线观看| 夜夜嗨av一区二区三区免费区| 国产亚洲精品久| 欧美视频在线观看免费| 老司机精品视频一区二区三区| 99亚洲一区二区| 亚洲成色www8888| 欧美资源在线观看| 99www免费人成精品| 在线精品国产成人综合| 国产精品视频一| 欧美精品v国产精品v日韩精品| 久久精品国产一区二区电影| 亚洲一区二区三区高清| 亚洲精品久久久久久久久久久久久 | 国产日韩欧美三级| 欧美性大战久久久久久久蜜臀| 欧美成人69av| 久久综合中文色婷婷| 欧美有码视频| 亚洲制服少妇| 在线亚洲高清视频| 99ri日韩精品视频| 亚洲激情国产精品| 欧美激情视频在线播放| 免费欧美在线| 蜜桃伊人久久| 久久综合色播五月| 久久久精品国产免费观看同学| 午夜视频一区二区| 亚洲欧美精品在线观看| 亚洲一区二区在线视频| 在线视频亚洲| 亚洲一区免费| 亚洲欧美日韩在线播放| 亚洲在线成人精品| 亚洲女优在线| 午夜精品久久久久99热蜜桃导演| 亚洲一区制服诱惑| 亚洲女女女同性video| 亚洲视频综合在线| 亚洲女同精品视频| 欧美在线日韩在线| 久久精品亚洲精品| 老司机午夜精品视频在线观看| 狂野欧美一区| 亚洲国产黄色片| 亚洲欧洲精品一区二区三区不卡| 91久久线看在观草草青青| 亚洲精品网站在线播放gif| 日韩香蕉视频| 午夜国产欧美理论在线播放 | 亚洲大胆av| 日韩视频在线一区二区三区| 国产精品99久久久久久宅男| 亚洲专区一区| 久久精品国产免费观看| 嫩草成人www欧美| 欧美日韩成人一区| 国产九九精品| 亚洲人成免费| 午夜天堂精品久久久久| 久久香蕉精品| 一区二区不卡在线视频 午夜欧美不卡' | 99ri日韩精品视频| 亚洲欧美一区二区三区久久 | 亚洲视频中文| 欧美中文字幕在线| 欧美激情一区在线| 亚洲一级黄色av| 欧美成年人网| 国产一区二区三区不卡在线观看 | 国产日韩欧美精品在线| 91久久线看在观草草青青| 亚洲一区二区三区四区在线观看| 久久噜噜噜精品国产亚洲综合| 91久久午夜| 久久精品99国产精品日本| 欧美日韩一区二区三区免费看 | 国产一区二区高清| 亚洲美女电影在线| 久久激情一区| 在线中文字幕一区| 另类图片综合电影| 国产精品亚洲产品| 一区二区三区日韩精品| 久久亚洲春色中文字幕| 亚洲综合国产精品| 欧美日韩精品欧美日韩精品| 激情文学综合丁香| 欧美在线精品免播放器视频|