2011-03-22 56 views
1

在談論錯誤處理時,我有點困惑。例如,以Direct2D爲例。 之前,我們可以開始使用Direct2D的功能,我們必須創建一個ID2DFactory對象:關於編程中的通用錯誤處理的問題

HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &d2d1Factory); 

正如你可以看到從上面。我們可以檢查HRESULT hr以查看我們是否成功創建了ID2DFactory。 我認爲當這個調用失敗時,即使我再次調用它,仍然失敗。我們沒有任何方法可以從此故障中恢復。

那麼檢查返回值有什麼意義?是否可以在終止程序之前告訴用戶出了什麼問題?

另一個例子是內存不足。當我們遇到罕見的情況時,我們沒有足夠的記憶來讓我們的程序「新」一些對象。 在C++中,當運行內存不足時,new運算符可能會返回NULL或引發錯誤。如果您沒有測試它是否爲NULL並且沒有發現錯誤,那麼程序將終止。我認爲你的程序不能從這種情況中恢復過來。

那麼,檢查是否存在一個嚴重的錯誤,你無能爲力?

回答

1

像D2D1CreateFactory()這樣的初始化函數可能會失敗。這種故障通常意味着您的PC上的操作系統已完全損壞,您需要重新啓動。這些信息對於用戶來說很有價值,他們想知道「O/S是否被洗掉,重新啓動並重試」與「在模塊mod.c中類似2345處取消引用無」。如果你不抓住錯誤條件,你所有的用戶都知道程序崩潰了。

捕獲錯誤返回和異常,並將它們報告給用戶是將好程序和差程序分開的許多事情之一。

特別是對於新的程序,您的程序通常有很多選項。它可能能夠重新請求一個較小的初始內存塊。它可能會返回內存緩存值,然後再試一次。它可以保存文件以準備退出,這也具有返回內存的效果。

當您處理錯誤返回或異常時,您有四個選擇;中止,交替,重試,失敗。

放棄是清理並退出;最好是返回資源,關閉文件和保存在製品。

交替嘗試一種完全不同的方法來做同樣的事情;像嘗試ftp,如果你不能使用http。交替是最難的錯誤恢復方法,坦率地說,大多數情況下,只有美國國家航空和航天局有預算來編寫這種錯誤處理。

重試是簡單地再次嘗試相同的操作。如果失敗是暫時的,這可能是成功的。如果故障持續存在,重試會導致無限循環,因此重試最好使用限制計數器或指數級增加的時間延遲。

失敗是簡單地刪除請求或操作並嘗試處理下一個請求。失敗可能看起來很愚蠢,因爲這意味着未執行請求,屏幕未更新,或用戶輸入被忽略。但令人驚訝的是,用戶可以通過在程序外執行某些操作來恢復這種錯誤,或者在情況不同的情況下再次嘗試。在大多數情況下,如果程序終止,它會完全拒絕用戶的服務,用戶可能能夠使用已損壞或部分正確的程序。 (嘗試想象一個飛行控制系統因爲它被解除引用而放棄,這不是你想要的。)

4

首先,不是每個錯誤都無法恢復。例如:如果文件用戶想要打開的文件不可用,程序可能想要將此報告給用戶並要求另一個文件打開。第二,即使程序不能繼續,它也必須有機會正常終止,告知用戶有關問題,保存狀態,記錄問題以備將來分析等,而不僅僅是崩潰。沒有錯誤檢查,程序很可能會崩潰。

+1

+1,錯誤報告是非常重要的。簡單的例子:想象一下,如果你的代碼不正確,編譯器會崩潰......錯誤報告的質量往往是底層程序質量的指標。 – 2011-03-22 18:31:32

2

曾經有客戶說過「它剛剛崩潰」的錯誤報告?當錯誤報告包含錯誤對話框的屏幕截圖,說明「D2D1CreateFactory返回E_...」時,它們會更有用。

0

可能有很多東西需要像打開的文件句柄一樣清理,或者某些數據庫操作需要在出錯時執行回滾等。在某些情況下,錯誤可能並不重要,程序可能只能繼續使用部分功能,而不是完全崩潰。最後但並非最不重要的是,它提供了有關發生錯誤的有價值的信息,這對調試非常有用。

順便說一句,除非你使用的是一些古代編譯器不符合,new不能按照C++標準返回NULL,否則在發生故障時必須拋出std::bad_alloc異常。

0

檢查返回值,這對調試是非常重要的。只需使用它的宏。

0

圖像兩個程序,每個程序都會遇到錯誤。

由於內存不足或其他原因導致內存崩潰,導致非法使用內存,操作系統顯示一些模糊的錯誤,或者只是默默關閉程序。

其他應用程序顯示更簡單的錯誤消息,然後回滾導致錯誤的操作,以便您可以決定是否要繼續和/或嘗試解決導致錯誤的條件。 (例如,也許關閉一些其他應用程序將允許有更多的內存。)

您寧願使用哪個程序?