程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++的可移植性和跨平台開發[3]:異常處理

C++的可移植性和跨平台開發[3]:異常處理

編輯:關於C++

上一個帖子“語法”由於篇幅有限,沒來得及聊異常,現在把和異常相關的部 分單獨拿出來說一下。

★小心new分配內存失敗

早期的老式編譯器生成的代碼,如果new失敗會返回空指針。我當年用的Borland C++ 3.1 似乎就是這樣的,現在這種編譯器應該不多見了。如果你目前用的編譯器還有這種行為,那 你就慘了。你可以考慮重載new操作符來拋出bad_alloc異常,便於進行異常處理。

稍微新式一點的編譯器,就不是僅僅返回空指針了。當new操作符發現內存告急,按照標 准的規定(參見03標准18.4.2章節),它應該去調用new_handler函數(原型為typedef void (*new_handler)();)。標准建議new_handler函數干如下三件事:1、設法去多搞點內存來; 2、拋出bad_alloc異常;3、調用abort()或者exit()退出進程。由於new_handler函數是可以 被重新設置的(通過調用set_new_handler),所以上述的行為它都可能有。

綜上所述,new分配內存失敗,有可能三種可能:1、返回空指針;2、拋出異常;3、進程 立即終止。如果你希望你的代碼具有較好的移植性,你就得把這三種情況都考慮到。

★慎用異常規格

異常規格在我看來不是一個好東西,不信可以去看看《C++ Coding Standards - 101 Rules, Guidelines & Best Practices》的第75條。(具體有哪些壞處以後專門開一個 C++異常和錯誤處理的帖子來聊)言歸正傳,按照標准(參見03標准18.6.2章節),如果一個 函數拋到外面的異常沒有包含在該函數的異常規范中,那麼應該調用unexcepted()。但是並 非所有編譯器生成的代碼都遵守標准(比如某些版本的VC編譯器)。如果你的需要支持的編 譯器在異常規范上的行為不一致,那就得考慮去掉異常規范聲明。

★不要跨模塊拋出異常

此處說的模塊是指動態庫。如果你的程序包含有多個動態庫,不要把異常拋到模塊的導出 函數之外。畢竟現在C++還沒有ABI標准(估計將來也未必會有),跨模塊拋出異常會有很多 不可預料的行為。

★不要使用結構化異常處理(SEH)

如果你從來沒有聽說過SEH,那就當我沒說,跳過這段。如果你以前習慣於用SEH,在你打 算寫跨平台代碼之前,要改掉這個習慣。包含有SEH的代碼只能在Windows平台上編譯通過, 肯定無法跨平台的。

★關於catch(...)

照理說,catch(...)語句只能夠捕獲C++的異常類型,對於訪問違例、除零錯等非C++異常 是無能為力的。但是某些情況下(比如某些VC編譯器),諸如訪問違例、除零錯也可以被 catch(...)捕獲。所以,你如果希望代碼移植性好,就不能在程序邏輯中依賴上述catch (...)的行為。

下一個帖子,准備聊一下和“硬件有關的跨平台問題”。

原始地址:http://program-think.blogspot.com/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved