vc下關於release和debug不同的討論(轉載)

在使用VC開發軟件的過程中,正當要享受那種興奮的時候突然發現:releasedebug運行結果不一致,甚至出錯,而release又不方便調試,真的是當頭一棒啊,可是疼歸疼,問題總要解決,下面將講述一下我的幾點經驗,看看是不是其中之一:


1.
變量。
 
大家都知道,debugrelease在初始化變量時所做的操作是不同的,debug是將每個字節位都賦成0xcc(1),而release的賦值近似於隨機(我想是直接從內存中分配的,沒有初始化過)。這樣就明確了,如果你的程序中的某個變量沒被初始化就被引用,就很有可能出現異常:用作控制變量將導致流程導向不一致;用作數組下標將會使程序崩 潰;更加可能是造成其他變量的不準確而引起其他的錯誤。所以在聲明變量後馬上對其初始化一個默認的值是最簡單有效的辦法,否則項目大了你找都沒地方找。代 碼存在錯誤在debug方式下可能會忽略而不被察覺到,如debug方式下數組越界也大多不會出錯,在release中就暴露出來了,這個找起來就比較難 了:( 還是自己多加註意吧

2. 自定義消息的消息參數。
 MFC
爲我們提供了很好的消息機制,更增加了自定義消息,好處我就不用多說了。這也存在debug release的問題嗎?答案是肯定的。在自定義消息的函數體聲明時,時常會看到這樣的寫法:afx_msg LRESULT OnMessageOwn(); Debug情況下一般不會有任何問題,而當你在Release下且多線程或進程間使用了消息傳遞時就會導致無效句柄之類的錯誤。導致這個錯誤直接原因是消 息體的參數沒有添加,即應該寫成:afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam); (2)

3. release模式下不出錯,但debug模式下報錯。
 
這種情況下大多也是因爲代碼書寫不正確引起的,查看MFC的源碼,可以發現 好多ASSERT的語句(斷言),這個宏只是在debug模式下才有效,那麼就清楚了,release版不報錯是忽略了錯誤而不是沒有錯誤,這可能存在很 大的隱患,因爲是Debug模式下,比較方便調試,好好的檢查自己的代碼,再此就不多說了。

4. ASSERT, VERIFY, TRACE..........調試宏
這種情況很容易解釋。舉個例子:請在VC下 輸入ASSERT然後選中按F12跳到宏定義的地方,這裏你就能夠發現DebugASSERT要執行AfxAssertFailedLine,而 Release下的宏定義卻爲"#define ASSERT(f) ((void)0)"。所以注意在這些調試宏的語句不要用程序相關變量如i++寫操作的語句。VERIFY是個例外,"#define VERIFY(f) ((void)(f))",即執行,這裏的作用就不多追究了,有興趣可自己研究:)


總結:
 Debug
Release不同的問題在剛開始編寫代碼時會經常發生,99%是因爲你的代碼書寫錯誤而導致的,所以不要動不動就說系統問題或編譯器問題,努力找找自己的原因纔是根本。我從前就常常遇到這情況,經歷過一次次的教訓後我就開始注意了,現在我所寫過的代碼我已經好久沒遇到這種問題了。下面是幾個避免的方面,即使沒有這種問題也應注意一下:

1. 注意變量的初始化,尤其是指針變量,數組變量的初始化(很大的情況下另作考慮了)
2.
自定義消息及其他聲明的標準寫法
3.
使用調試宏時使用後最好註釋掉
4.
儘量使用try - catch(...)
5.
儘量使用模塊,不但表達清楚而且方便調試。

1
afc(afc)
網友提供:
 debug
版初始化成0xcc是因爲0xccx86下是一條int 3單步中斷指令,這樣程序如果跑飛了遇到0xcc就會停下來,這和單片機編程時一般將沒用的代碼空間填入jmp 0000語句是一樣地

2
 
不知大家有沒有遇到過這種情況,具體原因我也不太清楚,是不是調用時按着默認的參數多分配了WPARAM+LPARAM的空間而破壞了應用程序的內存空間?還請高手來補充。

NightWolf 網友提供:我遇見過,好像是在函數調用的時候參數入棧的問題。因爲MFC的消息使用宏寫的,所以如果定義了OnMessage()的函數,編譯能夠通過,但是調用一次後,堆棧指針發生了偏移。然後就。。。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章