天天看點

try{} catch(…){}try{} catch(…){}

try{} catch(…){}

以前都是用try{} catch(…){}來捕獲C++中一些意想不到的異常,今天看了Winhack的文章才知道,這種方法在VC中其實是靠不住的。例如下面的代碼:

  1. try
  2. {
  3. BYTE * pch ;
  4. pch = ( BYTE * ) 00001234 ; // 給予一個非法位址
  5. * pch = 6 ; // 對非法位址指派,會造成Access Violation 異常
  6. }
  7. catch ( ... )
  8. {
  9. AfxMessageBox ( " catched " ) ;
  10. }

這段代碼在debug下沒有問題,異常會被捕獲,會彈出”catched”的消息框。但在Release方式下如果選擇了編譯器代碼優化選項,則 VC編譯器會去搜尋try塊中的代碼, 如果沒有找到throw代碼,他就會認為try catch結構是多餘的, 給優化掉。這樣造成在Release模式下,上述代碼中的異常不能被捕獲,進而迫使程式彈出錯誤提示框退出。

那麼能否在release代碼優化狀态下捕獲這個異常呢, 答案是有的。 就是__try, __except結構,上述代碼如果改成如下代碼異常即可捕獲。

  1. __try
  2. {
  3. BYTE * pch ;
  4. pch = ( BYTE * ) 00001234 ; // 給予一個非法位址
  5. * pch = 6 ; // 對非法位址指派,會造成Access Violation 異常
  6. }
  7. __except ( EXCEPTION_EXECUTE_HANDLER )
  8. {
  9. AfxMessageBox ( " catched " ) ;
  10. }

但是用__try, __except塊還有問題, 就是這個不是C++标準, 而是Windows平台特有的擴充。而且如果在使用過程中涉及局部對象析構函數的調用,則會出現C2712 的編譯錯誤。 那麼還有沒有别的辦法呢?

當然有, 就是仍然使用C++标準的try{}catch(..){}, 但在編譯指令行中加入 /EHa 的參數。這樣VC編譯器不會把try catch子產品給優化掉了。

MFC
上一篇: Try Catch
下一篇: try(){}catch(){}