Can you summarize the following document?
        
  硬體的異常處理機制由 CPU 完成。這種機制支援錯誤檢測,在發生錯誤後會將程式流跳轉到專門的錯誤處理過程(英語:error handling routines)中。發生異常前的狀態儲存在棧上。

  針對程式中可能發生的異常,作業系統可能通過 IPC 來提供對應的處理設施。程序執行過程中發生的中斷通常由操作提供的「中斷服務子程式」處理,作業系統可以藉此向該程序傳送訊號。程序可以通過註冊訊號處理器的方式自行處理訊號,也可以讓作業系統執行預設行為(比如終止該程式)。  從程序的視角,硬體中斷相當於可恢復異常,雖然中斷一般與程式流本身無關。

  在程式語言領域,通常 異常(英語:exception)這一術語所描述的是一種資料結構,該資料結構可以儲存異常(exceptional)相關資訊。異常處理的常見的一種機制是移交控制權。引發異常,也叫作拋異常,通過該方式達到移交控制權的效果。異常丟擲後,控制權會被移交至某處的接,並執行處理。  從子程式作者的角度看,如果要表示當前子程式無法正常執行,丟擲異常是很好的選擇。無法正常執行的原因可以是輸入引數無效(比如值在函式的定義域之外),也可以是無法獲得所需的資源(比如檔案不存在、硬碟出錯、記憶體不足)等等。在不支援異常的系統中,子程式需要通過返回特殊的實現類似的功能。然而返回錯誤碼可能導致,子程式的使用方需要編寫額外的程式碼,才能將普通的返回值與錯誤碼相區別。  程式語言對異常有著截然不同的定義,但現代語言大致上可分兩類:  Kiniry 強調“語言的設計僅僅部分地影響了異常機制的使用,結果上,(在整個系統的執行期間)形成的對異常使用的態度會處理影響部分或者所有的失敗(錯誤)。另外,其他主要的影響還有示例、核心程式碼的編寫、技術書籍雜誌文章以及相關討論”。

  在1960/1970年代,Lisp語言發展出軟體異常。最初版本是在1962年 Lisp 1.5的時候,這時候異常通過codice_1關鍵詞進行捕捉,並在出錯時候,通過codice_2進行返回,而不是以前的終止程式或者進行偵錯程式。1960年代後半,MacLisp語言通過codice_3關鍵詞引入引發錯誤機制。Lisp的這種創新不僅僅被應用於丟擲錯誤,還被應用於非本地控制流(non-local control flow)。在在1972年6月,MacLisp 語言通過codice_4 和codice_5兩個新的關鍵詞來實現非本地控制流,並保留codice_1 和 codice_3 專門做錯誤處理。在1970中後,codice_2衍生清除操作(LISP的新功能),對應著現今常見的codice_9。該操作也被 Common Lisp使用了。與之同時代,Scheme也誕生了codice_10,用於處理closures中的異常。 and 是首篇文章介紹結構化的異常處理。 1980年後,異常處理被廣泛利用於許多程式語言。  PL/I語言使用的是動態域異常,然而稍微現代的程式語言多用詞法作用域的異常。PL/I語言的異常處理包含事件(不是錯誤)、注意、EOF、列舉了的變數的修改。雖然現在的一些程式語言支援不含錯誤資訊的異常,但是他們並不常見。  一開始,軟體的異常處理是包含恢復的異常(恢復語法,就像大部分的硬體異常一樣)和不恢復的異常(終止語法 )。但是,在1960/1970時代,在實踐中得出恢復語句是十分低效的(C++標準相關的討論可見),因此恢復語句就很少再出現了,通常只能在類似Common Lisp和Dylan這種語言中見到。

  1980年Tony Hoare 在異常處理上提出了反對意見,這樣描述Ada語言時,認為異常處理是十分危險那的。  對於軟體而言,異常處理經常無法正確的處理,尤其是當這裡有多種來自不同原始碼的異常時。在對五百萬行Java程式碼進行資料流分析時,我們發現了超過1300個異常處理。這是1999-2004年的前沿報告以及他們的結論,Weimer 和 Necula寫到,異常是一個十分嚴峻的問題,他們會創造隱藏的控制流途徑,這種途徑是程式設計人員很難去推理的。  Go語言的初始版本並沒有異常處理,而因此被有的開發者認為控制流十分冗餘。後來,追加了類似的異常處理的語法/機制,但是Go語言的作者建立這僅僅在整個程式不可恢復的錯誤時候使用它。  異常,作為一個非結構化的流程,它會增加資源洩露的可能性(如:從鎖住的程式碼中逃脫,在開啟檔案時候逃脫叼),也有可能導致狀態不一致。因此,出現了集中異常處理的資源管理技術,最常見的結合Dispose pattern和解除保護一起使用(如codice_9語句),會在這段程式碼的控制權結束時自動釋放資源。

  錯誤處理(error handling)是通過處理函式的返回值的形式從而處理錯誤的一種程式設計方式。在Go等返回值可為複數的語言中,可通過將其中一個值設為錯誤值,從而達到錯誤處理的效果。 f, err := os.Open("filename.ext") if err!= nil { // do something with the open *File f 在僅僅支援返回狀態碼的語言裡,可通過處理錯誤碼,達到錯誤處理的效果。shell語言可通過codice_12獲得函式執行的退出碼,從而判斷是否出錯。  在其他語言中,可以通過判斷結果的某一個特徵,從而達到錯誤處理部分的效果,但不意味著這些語言自身支援錯誤處理。如,Java等物件導向的語言往往會通過null值判斷是否執行失敗,但有時候也會通過異常處理判斷是否執行失敗。

  如果一個異常丟擲後,沒有被捕捉,那麼未捕捉異常將會在執行時被處理。進行該處理的程式(routine)叫 未捕捉異常處理器()。大部分的處理是終止程式並將錯誤資訊列印至控制檯,該資訊通常包含除錯用(debug)的資訊,如:異常的描述資訊、棧追蹤(stack trace)。通常處於最高階(應用級別)的處理器,即便捕捉到異常也會避免終止自身(如:執行緒出現異常,主執行緒也不會終止)。  值得了解的是,在即便未捕捉異常導致了程式異常中斷(如:異常沒被捕捉、滾動未完成、沒釋放資源),程式仍舊能正常地順序性地關閉。只要確保執行時(runtime)能正常地執行,因為 執行時 控制著整個程式的執行。  作為預設的未捕捉異常處理器是可以被替換的,不管是全域性還是單執行緒的,新的未捕捉異常處理器可以嘗試做這些事情:未捕捉異常導致關閉了的執行緒,使之重啟;提供另一種方式記錄日誌;讓使用者報告未捕捉異常等等。在Java中,單一執行緒可以使用codice_13,全域性可以用codice_14;在python中,可通過修改codice_15。

  

  Java的設計者設計了 檢查性異常(Checked exceptions)。當方法引發“檢查性異常”時,“檢查性異常”將成為方法符號的一部分。例如:如果方法丟擲了codice_16,我們必須顯式地使用方法符號(在Java中是codice_17),如果不這樣做的話將會導致編譯時錯誤(compile-time error)。

  許多常見的程式設計語言,包括Actionscript,Ada,BlitzMax,C++,C#,D,ECMAScript,Eiffel,Java,ML,Object Pascal(如Delphi,Free Pascal等),Objective-C,Ocaml,PHP(version 5),PL/1,Prolog,Python,REALbasic,Ruby,Visual Prolog以及大多數.NET程式設計語言,內建的異常機制都是沿著函式呼叫棧的函式呼叫逆向搜尋,直到遇到異常處理程式碼為止。一般在這個異常處理程式碼的搜尋過程中逐級完成棧捲回(stack unwinding)。但Common Lisp是個例外,它不採取棧捲回,因此允許異常處理完後在丟擲異常的程式碼處原地恢復執行。而 Visual Basic(尤其是在其早於.net 的版本,例如 6.0 中)走得更遠:codice_18 語句可輕易指定發生異常後是重試(codice_19)還是跳過(codice_20)還是執行程式設計師定義的錯誤處理程式(codice_21)。  多數語言的異常機制的語法是類似的:用codice_22或codice_23丟擲一個異常物件(Java或C++等)或一個特殊可擴充套件的列舉型別的值(如Ada語言);異常處理程式碼的作用範圍用標記子句(codice_24或codice_25開始的語言作用域)標示其起始,以第一個異常處理子句(codice_26等)標示其結束;可連續出現若干個異常處理子句,每個處理特定型別的異常。某些語言允許codice_27子句,用於無異常出現的情況。更多見的是codice_28子句,無論是否出現異常它都將執行,用於釋放異常處理所需的一些資源。  C++異常處理是資源獲取即初始化(Resource-Acquisition-Is-Initialization)的基礎。  C語言一般認為是不支援異常處理的。Perl語言可選擇支援結構化異常處理(structured exception handling)。  Python語言對異常處理機制是非常普遍深入的,所以想寫出不含codice_29的程式非常困難。

  在python裡只存在異常與語法錯誤(syntax errors)。語法錯誤是在執行之前發生的。而異常是在執行時發生的錯誤,它將無條件停止程式,除非進行捕捉處理。

  異常是異常事件(exceptional event)的縮寫。異常是一個事件,它發生在程式執行時並會打亂程式指示的正常流程。當方法出現了錯誤時,方法會建立一個物件並將它交給執行時系統(runtime system),所建立的物件叫 異常物件(exception object),該物件包含了錯誤的資訊(描述了出錯時的程式的型別和狀態)。建立錯誤物件和轉交給執行時系統的過程,叫 丟擲異常(throwing an exception)。  codice_30 和codice_31均是不檢查的異常(Unchecked Exceptions)。錯誤不等於錯誤類(codice_31),錯誤類代表著不應該被捕捉的嚴重的問題。codice_30 意味著程式出現問題了。

  Go語言提倡的是錯誤處理(error handling)。Go語言設計者系統希望使用者在錯誤出時,顯式地檢查錯誤。 Go雖然不提供與Java語言的codice_34同等的功能語句,但是取而代之,提供了輕型的異常處理機制codice_35。

  一段程式碼是異常安全的,如果這段程式碼執行時的失敗不會產生有害後果,如記憶體洩露、儲存資料混淆、或無效的輸出。異常安全可分成不同層次:  例如,考慮一個smart vector型別,如C++'s codice_36或Java's codice_37。當一個資料項codice_38插入vector codice_39,必須實際增加codice_38的值到vector的內部物件列表中並且修改vector的計數域以正確表示codice_39中儲存了多少資料項;此時如果已有的儲存空間不夠大,就需要分配新的記憶體。記憶體分配可能會失敗並丟擲異常。因此,vector資料型別如果是“失敗透明”保證將會非常困難甚至不可能實現。但vector型別提供“強異常安全”保證卻是相當容易的;在這種情況下,codice_38插入codice_39或者成功,或者codice_39保持不變。如果vector型別僅提供“基本異常安全”保證,如果資料插入失敗,codice_39可能包含也可能不包含codice_38的值,但至少codice_39的內部表示是一致的。但如果vector資料型別是“最小異常安全”保證,codice_39可能會是無效的,例如codice_39的計數域被增加了,但codice_38並未實際插入,使得內部狀態不一致。對於“異常不安全”的實現,程式可能會崩潰,例如寫入資料到無效的記憶體。  通常至少需要基本異常安全。失敗透明是難於實現的,特別是在編寫庫函式時,因為對應用程式的複雜知識缺少獲知。
異常處理 的英語是Exception handling。另外值得注意的是,大陸所用“”對應的英文是Abnormality,港澳臺以及日本使用的是“”。