try catch語句在VC下的處理


使用VC編譯QT程序碰到一個問題:

我在.h文件里定義:
    LoadingWidget* w;
然后.cpp文件里定義:

void MyClass::ModifyTask()
{
    // w = new LoadingWidget(); // 忘了生成實例
    try {
        w->show();    
    } catch (int e) {
        QMessageBox::warning(this, ("error"), ("Please input server address!"));
    }
}
盡管寫上了try catch,程序照樣崩潰,實在是夠差勁的。后來找到一篇文章:

----------------------------------------------------------------------

try{} catch(…){}
以前都是用try{} catch(…){}來捕獲C++中一些意想不到的異常, 今天看了Winhack的帖子才知道,這種方法在VC中其實是靠不住的。例如下面的代碼:
try
{
BYTE* pch ;
pch = ( BYTE* )00001234 ; //給予一個非法地址

*pch = 6 ; //對非法地址賦值,會造成Access Violation 異常
}
catch(...)
{
AfxMessageBox( "catched" ) ;
}

這段代碼在debug下沒有問題,異常會被捕獲,會彈出”catched”的消息框。 但在Release方式下如果選擇了編譯器代碼優化選項,則VC編譯器會去搜索try塊中的代碼, 如果沒有找到throw代碼, 他就會認為try catch結構是多余的, 給優化掉。 這樣造成在Release模式下,上述代碼中的異常不能被捕獲,從而迫使程序彈出錯誤提示框退出。
那么能否在release代碼優化狀態下捕獲這個異常呢, 答案是有的。 就是__try, __except結構, 上述代碼如果改成如下代碼異常即可捕獲。
__try
{
BYTE* pch ;
pch = ( BYTE* )00001234 ; //給予一個非法地址

*pch = 6 ; //對非法地址賦值,會造成Access Violation 異常
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
AfxMessageBox( "catched" ) ;
}

但是用__try, __except塊還有問題, 就是這個不是C++標准, 而是Windows平台特有的擴展。 而且如果在使用過程中涉及局部對象析構函數的調用,則會出現C2712 的編譯錯誤。 那么還有沒有別的辦法呢?
當然有, 就是仍然使用C++標准的try{}catch(..){}, 但在編譯命令行中加入 /EHa 的參數。這樣VC編譯器不會把try catch模塊給優化掉了。

----------------------------------------------------------------------

總結:盡管這篇文章解釋的比較清楚,不過我還是覺得相當的友邦驚詫。因為delphi里就可以捕捉任何錯誤,java好像也是這樣。寫throw相當於程序員已經預料到了會出現什么錯誤,還不如寫正常的代碼來個else判斷就行了。這樣的try catch實在是意義不大。不過微軟是老牌帝國,它對try catch這樣理解,肯定還有更深層次的原因。

參考:http://blog.csdn.net/yu444/article/details/5612714


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM