無版本差異
我來了,我編碼了,我崩潰了。-- julius c'ster
所有的程式都要應付錯誤。錯誤是不在程式正常操作範圍內的異常情況:常見的錯誤情況
有:• 記憶體耗盡。
• 磁碟空間耗盡。
• 檔名無效。
• 試圖寫唯讀檔案。
• 試圖讀不存在的檔案。
• 請求不支援的系統服務。
21.1 錯誤處理問題
c 語言檢測報告錯誤的傳統方法並沒形成傳統,每個函式都有自己的方法,包括:
• 返回 null 指標。
• 返回 0 值。
• 返回非零的錯誤**。
• 需要檢查 errno。
• 如果上述檢查失敗了,需要呼叫乙個函式。
為了處理可能出現的錯誤,必須為每個函式新增繁瑣的錯誤處理**。如果發生了錯誤,必
須有錯誤恢復**,並且需要有**將錯誤以某種友好的方式告訴給使用者。如果不能在發生
錯誤的區域性環境處理錯誤,就必須顯式地將錯誤傳播給它的呼叫者。如果要顯示錯誤型別,
需要將一大堆 errno 值轉換為合適的文字。這些**可能占用整個專案編碼時間的一大部
分,而且如果執行時系統加入了乙個新的 errno 值,舊有的**就不能顯示有意義的資訊。
功能良好的錯誤處理**很容易將清晰而簡潔的實現搞得一團糟。
更糟的是,功能良好的錯誤處理**本身就很容易出錯,還總是整個專案中測試最不充分的
部分(因此充滿錯誤),並且還總是被簡單地省略。最終的結果就如同「藍屏宕機」那樣,
程式由於無法處理一些未預料到的錯誤而失敗。
並不值得為「快速而髒的(quick and dirty)」程式編寫錯誤處理**,因此使用這類程式就好
像使用沒有鋸罩的多功能台式電鋸。
我們所需要的是如下的錯誤處理哲學和方法學:
• 標準化——如果用法一致,它就更有用。
• 就算程式設計師無法查出出現了什麼錯誤,也要使程式以合適的方式終止。
• 在無需改動舊**的前提下就可以加入新的錯誤型別,從而重用舊的**。
• 不會由於粗心大意而忽略某些錯誤。
• 重寫「快速而髒的」程式直到能夠正確處理錯誤。
• 可以很容易地寫出清晰的錯誤處理**。
197第 21 章 d 中的錯誤處理 — 張雪平
21.2 d 的錯誤處理解決方案
先讓我們觀察一下並對錯誤作出以下假設:
• 錯誤不屬於正常的程式流。錯誤是異常的、不常見的、不該出現的。
• 因為錯誤不常見,所以錯誤處理**的效能並不十分重要。
• 程式的正常邏輯流的效能很關鍵。
• 所有的錯誤必須採用統一的方式處理,不論是顯式地編寫**處理它們還是採用系統
預設的處理方式。
息。解決方案是使用異常處理來報告錯誤。所有的錯誤都是從抽象類 error 派生的物件。error
類有乙個叫做 tostring() 的純虛函式,它返回乙個 char 型別的人類可讀的錯誤描述。
如果**檢測到了乙個錯誤,如「記憶體耗盡」,則丟擲 error 物件,其中包含訊息「記憶體耗
盡」。函式呼叫堆疊會被展開,並查詢 error 的處理程式。隨著堆疊的展開,相應的
finally 塊 會被執行。如果找到了錯誤處理程式,就在該處恢復程式的執行。否則,會執行
預設的錯誤處理程式,該程式會顯示錯誤訊息並終止程式。
這個解決方案是否能滿足我們的要求?
標準化——如果用法一致,它就更有用。
這正是 d 的方法,d 執行時庫和示例都採用這種方式。
就算程式設計師無法查出出現了什麼錯誤,也要使程式以合適的方式終止。
如果沒有相應的錯誤處理程式,程式會執行預設的錯誤處理程式,該處理程式列印出
適當的訊息,並使程式優雅的推出。
在無需改動舊**的前提下就可以加入新的錯誤型別,從而重用舊的**。
舊的**可以決定是捕獲所有的錯誤,或者是只捕獲特定的錯誤並向上傳播剩餘的錯
誤。無論那種情況,都不必為每個錯誤**關聯乙個訊息了,編譯器會自動為其提供
正確的訊息。
不會由於粗心大意而忽略某些錯誤。
異常會採用這種或那種方式處理。不會出現使用 null 指標表示出錯,但後面的**
卻試圖使用該 null 指標的情況。
重寫「快速而髒的」程式直到能夠正確處理錯誤。
「快速而髒的」**根本不需要包含任何錯誤處理**,也不需要檢查錯誤。錯誤會
被預設的處理程式捕獲,顯示適當的訊息,然後程式會優雅的終止。
可以很容易地寫出清晰的錯誤處理**。
try/catch/finally 語句比那些無窮無盡的 if (出錯) goto 處理程式; 語句要清晰得多。
這個解決方案是否符合我們對於的錯誤的假設?
錯誤不屬於正常的程式流。錯誤是異常的、不常見的、不該出現的。
d 的異常處理機制完全符合上述假定。
因為錯誤不常見,所以錯誤處理**的效能並不十分重要。
異常處理堆疊的展開相對較慢。
198第 21 章 d 中的錯誤處理
程式的正常邏輯流的效能很關鍵。
因為正常的**流不必檢查每個函式呼叫的返回值是否代表出錯,使用異常處理來處
理錯誤確實會使程式執行得更快。
所有的錯誤必須採用統一的方式處理,不論是顯式地編寫**處理它們還是採用系統預設的
處理方式。
如果某個錯誤沒有對應的處理程式,就會由執行時庫中的預設處理程式處理。如果一
個錯誤被忽略了,那一定是程式設計師特意新增了**用於忽略這個錯誤,因此這一定是
在程式設計師意料之中的。
不需要將錯誤**翻譯為人類可讀的字串,錯誤檢測**而不是錯誤恢復**負責
生成正確的字串。這種做法也使不同的程式出現相同的錯誤時會輸出相同的訊息。
使用異常來處理錯誤會導致其它的問題——如何寫出異常安全的程式。這裡有關於怎麼做的
說明。
D語言中的錯誤處理
所有的程式都要應付錯誤。錯誤是不在程式正常操作範圍內的異常情況 c 語言檢測報告錯誤的傳統方法並沒形成傳統,每個函式都有自己的方法,包括 為了處理可能出現的錯誤,必須為每個函式新增繁瑣的錯誤處理 如果發生了錯誤,必須有錯誤恢復 並且需要有 將錯誤以某種友好的方式告訴給使用者。如果不能在發生錯誤的區域...
MySql錯誤處理 錯誤處理的例子
有幾種錯誤處理的宣告形式 如果任何錯誤 不是 not found 設定 l error 為 1 後繼續執行 declare continue handler for sqlexception set l error 1 如果發生任何錯誤 不是 not found 執行 rollback和產生一條錯誤...
swift 中錯誤處理
enum customerror error 定義乙個測試用的類 class testerrorclass name s func showstring 第一種使用方式,執行 後,直接丟擲異常,中止執行 let tes trytesterrorclass s 執行結果 lldb expr 123.c...