2015-04-08 27 views
1

我最近遇到了一個使用幾個第三方庫的問題。我的代碼叫庫A,它叫庫B.當庫B遇到錯誤時,它會拋出異常;這是首選的行爲,因爲它不知道應該如何處理錯誤。庫A將在其虛擬析構函數中使用RAII清理其內部資源。C++異常處理被析構函數阻止

由於這些資源對於A中的類是私有的,因此我正在使用我無法提前清理資源。

現在在清理類中的某些情況下,我在我的代碼中使用了A中的析構函數;而反過來被稱爲B和B的則會拋出異常。

我想在我的代碼中發現這個異常,因爲我不想更改第三方庫的代碼。不幸的是,我發現異常處理代碼不會將異常傳播回我的代碼,但會導致調用異常終止方法。

我最終改變了A的第三方代碼來捕捉並忽略所有可能的異常。

由於默認情況下,gcc 4.8.1不會通過析構函數傳播異常,哪些主要編譯器和這些編譯器的版本將通過析構函數傳播異常?

+0

我無法解釋您的問題。一個代碼示例會有所幫助。無論如何,這是否會發生,有沒有機會? 「** 15.2/1 **當控制從拋出異常的地方傳遞到處理程序時,析構函數由本節中指定的進程調用,稱爲* stack unwinding *。如果直接由堆棧解繞調用的析構函數退出除了例外,調用了「std :: terminate」(15.5.1)。「 –

+0

MyCode清理A中定義的類。A調用B清理其內部成員。 B拋出異常。 M - > A(析構函數) - > B(例外)。這不是作爲堆棧展開的一部分完成的。 B所擁有的資源是一個套接字連接,並且已經處於不良狀態,這就是爲什麼我要清除套接字的用法,以便重新創建套接字連接。這是一個更大的系統的一部分,我不想崩潰,尤其是在我試圖解決問題的操作上。 –

回答

0

我確實認爲它是在標準的某個地方定義的,即從析構函數拋出的異常可能導致調用std::terminate,至少在C++ 11中是如此。這是因爲編譯器將析構函數隱式標記爲noexcept

+0

種:http://stackoverflow.com/questions/15721544/destructors-and-noexcept/http://stackoverflow.com/questions/9180164/implicit-generated-members-and-noexcept和https:// akrzemi1。 wordpress.com/2013/08/20/noexcept-destructors/ –

+0

我喜歡這篇文章:https://akrzemi1.wordpress.com/2013/08/20/noexcept-destructors。謝謝。編譯器的後續工作以及何時每個編譯器中的行爲發生變化將會很有幫助,因爲此代碼是跨平臺的,並且可以在具有多個不同版本的同一編譯器的許多不同機器上運行。 –