首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 跨平台開發實戰 (三):異常處理移植性陷阱與最佳實務

     編輯:關於C++

new 失敗的三種可能行為

編譯器類型行為應對
極舊 (預 C++98)回傳 nullptr檢查回傳值或重載 operator new 拋出 bad_alloc
標準相容呼叫 new_handler → 拋出 bad_alloc / abort() / 嘗試釋放記憶體捕獲 bad_alloc;可自訂 set_new_handler
部分配置直接 abort()/exit()無法捕獲,設計上避免大量單次分配

可移植代碼必須同時處理三種情況。

慎用異常規格 throw(...)

  • C++11 棄用,C++17 移除 (改用 noexcept)。
  • 標準規定違反規格呼叫 unexpected(),但 MSVC 等編譯器不執行檢查。
  • 異常規格阻礙編譯器優化,增加二進制體積。
  • 建議:完全移除動態異常規格,改用文件/註解說明可能拋出異常。

跨動態庫拋出異常:高風險禁區

  • C++ 無標準 ABI,不同編譯器/版本/編譯選項下異常物件佈局、展開表格式皆不同。
  • 跨 .dll/.so 邊界拋出異常 → 未定義行為 (崩潰、資源洩漏、靜默錯誤)。
  • 鐵律:動態庫導出介面只能使用 C 風格錯誤碼 或 std::error_code,異常必須在庫內部捕獲轉換。

結構化異常處理 (SEH) 僅限 Windows

  • __try/__except/__finally 為 MSVC 擴充,無法跨平台編譯。
  • 跨平台專案嚴禁使用 SEH,統一用 C++ 標準 try/catch。

catch(...) 捕獲範圍不一致

  • 標準:僅捕獲 C++ 異常 (衍生自 std::exception 或任意型別 throw)。
  • MSVC (特定選項 /EHa):亦捕獲硬體例外 (存取違規、除零、堆疊溢位)。
  • 不可依賴 catch(...) 捕獲硬體例外 實作程式邏輯。硬體例外應由作業系統/執行期處理 (如崩潰轉儲)。

異常安全等級與 RAII

等級保證實作關鍵
基本承諾不洩漏資源、物件保持有效狀態RAII 封裝所有資源
強烈承諾操作失敗狀態回滾如未執行Copy-and-swap / 交易式修改
不拋出承諾操作絕不拋出異常noexcept、避免分配/鎖
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved