2015-10-01 33 views
3

我有這樣的代碼:覆蓋默認未處理的異常行爲

#include <iostream> 
#include <exception> 

class TestException : public std::exception 
{ 
public: 
    char const* what() const throw() override { return msg_.c_str(); } 

protected: 
    std::string & message() throw() { return msg_; } 

private: 
    std::string msg_; 
}; 

void ThrowIt() 
{ 
    throw TestException(); 
} 

int main() 
{ 
    ThrowIt(); 
} 

建時在任一版本或調試上在程序終止Visual Studio的結果而編制的Windows運行此,同去的時候用GCC在Linux編譯機,結果是:中止

扔 'TestException'
什麼()的一個實例後終止叫

一旦發現未處理的異常,它們都會終止程序。這種行爲是嚴格系統特定的還是由標準規定的?有沒有一種跨平臺的方式,我可以將每個未由catch處理的異常重新路由到處理程序,而不是僅僅終止程序?

回答

0

15.5.1 C++的11個標準狀態

[...]當異常處理機制無法找到一個拋出的異常處理程序[...] std::terminate()被稱爲。在沒有找到匹配處理程序的情況下, 它是實現定義的,無論在調用std::terminate()之前堆棧是否展開。

所以終止是標準行爲,但是否可以從這種情況中恢復是實現定義的。在任何情況下,都不會重新路由異常對象。

您還可以更改std::terminate()調用的處理函數(typedef void (*terminate_handler)();)和terminate_handler set_terminate(terminate_handler f) noexcept;,並使用terminate_handler get_terminate() noexcept;查看它。

+0

編輯'的std :: terminate'處理程序不會讓我查看拋出的異常,在第一造成'的std :: terminate'地點,對嗎? –

+0

@JameyD Yup,這就是你從標準中得到的一切。 –

0

在您的代碼中,您有一個未捕獲的異常,因爲您的異常沒有匹配的句柄。此行爲在[except.terminate]中進行了說明

在某些情況下,必須放棄異常處理以減少細微的錯誤處理技術。 [注意:這些情況是:
[...]
- 當異常處理機制無法找到一個處理程序拋出的異常(15.3),或 [...]

然後我們有

在這種情況下,調用std :: terminate()(18.8.3)。在沒有找到匹配處理程序的情況下, 它是實現定義的,無論堆棧在未調用std :: terminate()之前是否被解除。

如果你想擁有「頂級」 catch將處理程序中的所有異常,如果不抓住你可以在一個try...catch塊包裹代碼main()。未捕獲的任何異常將會按[除外。處理]

如果處理程序try塊中沒有發現匹配,對於匹配的處理器搜索在同一個線程的動態 周圍try塊繼續。

你也改變std::terminate_handler使用std::set_terminate

+0

是的,我知道我有一個未捕獲的異常,那是程序的目標。我試圖避免「趕上(...)」。正如問題所述,我想知道是否可以添加一個跨平臺的處理程序來處理那些沒有被catch塊攔截的異常。 –