2015-04-02 39 views
0

下面是C++編程一個不太常見的問題:如何避免由於意外異常導致的問題?

程序員寫了一個C++庫(我們叫它美孚),其中包括程序員B的程序調用的方法,一個漂亮的公共API,以實施他的計劃的一部分。在使用Foo API時,程序員B會查看文檔和頭文件,但不會在.cpp文件中使用,主要是因爲擁有公共API的全部要點是隱藏實現細節。程序員B讓他的程序工作,最初一切看起來都很好。

一天的程序是做它的事,當一些不尋常的美孚代碼庫,導致一個Foo方法拋出異常發生裏面。程序員B不知道那種類型的異常可能會被Foo方法拋出,所以這個異常不會被捕獲(並且程序崩潰),或者異常被一個非常普通的異常處理程序捕獲(例如catch()。 ..))並沒有得到充分的處理(所以程序做了一些非最優化的事情,比如用一個神祕的錯誤信息來建立一個對話框)。

因爲我想我的C++軟件是強大的,我的問題是,什麼是避免像上述方案中的好方法嗎?要求程序員B讀取Foo代碼庫中的所有.cpp文件(以及Foo調用的任何C++代碼庫的所有.cpp文件,以此類推),尋找throw語句似乎不是一個合適的解決方案,因爲它違背了封裝的精神,即使這樣做,也不能保證將來可能不會添加更多的投擲語句。要求程序員A記錄所有可能拋出的異常似乎是一個好主意,但實際上程序員A很可能會錯過其中的一些,特別是如果他的代碼又調用另一個庫,可能或不可能記錄其中的100%可能的例外。

在Java中,有一些支持自動化的異常處理檢查;例如你可以註釋你的Java方法來聲明它們可能拋出什麼異常,如果調用的代碼沒有明確地處理所有這些異常(或者它本身聲明它可能會拋出異常),那麼編譯失敗,程序員被迫修復它程序 - 從而防止上述的問題情況。另一方面,C++沒有這樣的編譯時執行,這意味着驗證C++程序正確處理所有異常似乎完全取決於程序員和QA團隊。但是在一個非平凡的程序中,實際執行這種驗證似乎不切實際;有沒有一些技術(自動化或非自動化),C++程序員可以通過這些技術獲得他們的程序以一種被認爲的方式處理所有可能拋出的異常的信心? (哪怕只是一個程序,它會列出所有可以從不同的調用拋出的異常的將是有益的,我覺得 - 至少那麼會是已知的可能性列表要檢查的異常處理代碼)

+0

請注意,Java異常註釋不適用於所有異常。例如,它們不適用於NullPointerExceptions,因爲這需要將每個解引用包含在try/catch塊中,這將非常繁瑣,以至於任何人都不會使用Java。 – immibis 2015-04-02 06:33:16

+1

在代碼的某個位置用'catch(...)'嘗試'',這樣至少可以在出現這種情況時正常退出。如果你希望能夠從中恢復,那麼你需要在每次調用之後用包含'catch(...)'的代碼包裝B的API,並做適當的事情;然而,很難說什麼是「合適的」,因爲問題的本質是代碼的「B」部分可能是不可恢復的。 – 2015-04-02 07:10:10

+0

我想你的問題在第一段之後會切換「A」和「B」。我使用'B'作爲圖書館作者和'A'作爲使用圖書館的人並且接收到意外的異常。 – 2015-04-02 07:11:09

回答

2

起初看這個問題似乎有相當的困境。直到你發現以下的見解。

例外情形而言,是一個異常被拋出時,它拋出,並在那裏被捕獲的事實捕獲超過90%的拋出的異常的信息的重要性。例外的類型很少很重要。

事實證明,我們很少創建代碼,可以解決問題,並提出了補救方案。幾乎總是唯一有用的東西代碼可以做的是報告命令失敗和錯誤消息。

如果庫中使用的異常是從std :: exception派生的,並支持對what()的有用調用,那麼當您報告/記錄該消息時,您已轉移到捕獲95%的有用信息。如果what()消息包含__ FILE __,__ LINE __和__ func __信息,那麼您在大多數拋出異常提供的重要信息的98%處。

即使一個庫沒有被每個特定函數調用拋出的每個異常類型都仔細記錄下來,一個體面的庫將提供所有帶有拋出異常的基類型(通常是std: :異常或從中派生出來的東西)。這個異常基類將有一些獲取相關錯誤消息的方法(如what()調用)。

但是,即使您減少到使用catch(...)作爲最後一道防線,您的錯誤消息仍然可以指示命令失敗以及它是什麼命令。而且你有信心處理每一個可能引發的異常。

+0

感謝您的回答 - AFAICT描述了C++異常處理中的「最先進的技術」; OTOH我希望可能存在一些更強大/更全面的分析技術。特別是我正在尋找一種方法,我可以在編譯時審查所有可能引發的各種異常(例如,通過靜態代碼分析),以便我可以事先系統地驗證我的程序對這些響應的所有響應,而不是可能只有當用戶在現場失敗後(此時損壞已經完成)報告時才能找到一些角落案例。 – 2015-04-02 14:57:08

相關問題