程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 怎樣使C++編譯器實現異常處理

怎樣使C++編譯器實現異常處理

編輯:C++入門知識

在介紹C++編譯器的前提下,先要介紹一下什麼是C++編譯器C++編譯器是一個與標准化C++高度兼容的編譯環境,這點對於編譯可移植的代碼十分重要,編譯器對不同的CPU會進行不同的優化。

它將正常代碼 和錯誤處理代碼清晰的劃分開來,程序變得非常干淨並且容易維護。本文討論了編譯器如何實現異常處理。我將假定你已經熟悉異常處理的語法和機制。本文還提供 了一個用於VC++的異常處理庫,要用庫中的處理程序替換掉VC++提供的那個,你只需要調用下面這個函數:

  1. install_my_handler(); 

之後,程序中的所有異常,從它們被拋出到堆棧展開stack unwinding),再到調用catch塊,最後到程序恢復正常運行,都將由我的異常處理庫來管理。 與其它C++特性一樣,C++標准並沒有規定編譯器應該如何來實現異常處理。這意味著每一個編譯器的提供商都可以用它們認為恰當的方式來實現它。

下面我會 描述一下VC++是怎麼做的,但即使你使用其它的編譯器或操作系統①,本文也應該會是一篇很好的學習材料。VC++的實現方式是以windows系統的結 構化異常處理SEH)②為基礎的。

在本文的討論中,我認為異常或者是被明確的拋出的,或者是由於除零溢出、空指針訪問等引起的。當它發生時會產生一個中斷。接下來控制權就會傳遞到操作系統 的手中。操作系統將調用異常處理程序,檢查從異常發生位置開始的函數調用序列。

進行堆棧展開和控制權轉移。Windows定義了結構 "EXCEPTION_REGISTRATION",使我們能夠向操作系統注冊自己的異常處理程序。

  1. #include   
  2. #include   
  3.  
  4. using std::cout;   
  5. using std::endl;   
  6.  
  7. struct EXCEPTION_REGISTRATION   
  8. {   
  9.     EXCEPTION_REGISTRATION* prev;   
  10.     DWORD handler;   
  11. };   
  12.  
  13. EXCEPTION_DISPOSITION myHandler(   
  14.     _EXCEPTION_RECORD *ExcRecord,   
  15.     void * EstablisherFrame,   
  16.     _CONTEXT *ContextRecord,   
  17.     void * DispatcherContext)   
  18. {   
  19.     cout << "In the exception handler" << endl;   
  20.     cout << "Just a demo. exiting..." << endl;   
  21.     exit(0);   
  22.     return ExceptionContinueExecution; //不會運行到這   
  23. }   
  24.  
  25. int  g_div = 0;   
  26.  
  27. void bar()   
  28. {   
  29.     //初始化一個EXCEPTION_REGISTRATION結構   
  30.     EXCEPTION_REGISTRATION reg, *preg = ®    
  31.     reg.handler = (DWORD)myHandler;   
  32.  
  33.     //取得當前異常處理鏈的"頭"   
  34.     DWORD prev;   
  35.     _asm   
  36.     {   
  37.         mov EAX, FS:[0]   
  38.         mov prev, EAX   
  39.     }   
  40.     reg.prev = (EXCEPTION_REGISTRATION*) prev;   
  41.  
  42.     //注冊!   
  43.     _asm   
  44.     {   
  45.         mov EAX, preg   
  46.         mov FS:[0], EAX   
  47.     }   
  48.  
  49.     //產生一個異常   
  50.     int  j = 10 / g_div;  //異常,除零溢出   
  51. }   
  52.  
  53. int  main()   
  54. {   
  55.     bar();   
  56.     return 0;   
  57. }  

注意EXCEPTION_REGISTRATION必須定義在棧上,並且必須位於比上一個結點更低的內存地址上,windows對此有嚴格要求,達不到的話,它就會立刻終止進程。

  1. 簡介學習C++總結之談
  2. 對C++庫函數進行學習探索總結筆記
  3. C++類庫設計的基本構思與方法
  4. C++語言真的還有市場價值?
  5. C++類庫設計的基本構思與方法

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