![](/img/trans.png)
[英]std::rethrow_exception(nullptr) undefined behavior or bad_exception?
[英]Why bad_exception is not thrown automatically?
為什么這段代碼沒有錯誤運行? 遇到意外異常時,難道不應該自動調用bad_exception
嗎? 還是有必要為其設置處理程序?
#include <iostream>
#include <exception>
using namespace std;
class C{};
void test() throw(bad_exception)
{
throw C();
}
int main()
{
try
{
test();
} catch(bad_exception& e)
{
cout << "Caught ";
}
}
在C ++ 03理論中:如果引發的異常不在異常規范中,則將調用unexpected()
。 如果您尚未通過set_unexpected()
設置意外的處理程序, set_unexpected()
這意味着您將觀察到terminate()
被調用的情況。 如果您設置一個意想不到的處理程序不調用終止,但拋出一個異常,如果該異常不能在你的異常規范中列出,它被翻譯成bad_exception。 因此,為了獲得預期的結果,請首先使用適當的處理程序調用set_unexpected()
。
在C ++ 03的實踐中:有些編譯器根本不支持異常規范( throw()
除外),其他編譯器只是不評估/檢查其正確性。 正如Herb Sutter指出的那樣 ,異常規范創建了一個笨拙的“影子類型系統”,該系統很難正確處理(如果可能的話)。 因此..
...在C ++ 11中: 不贊成使用 Exception規范。 您寧可不要使用它們。 但是,有一個nothrow
運算符的功能與throw()
略有不同
PS:那么為什么C ++ 03中有std :: bad_exception? 您擁有三個不同的代碼區域:
因此,如果“外來”代碼引發了違反您的異常規范的異常,則可能會產生以下三種結果:
在函數內設置自己的處理程序將禁用任何其他僅想使用您的函數的人先前設置的處理程序。 他不會期望您禁用他的處理程序。 此外,該處理程序是一種全局的“假設-如果”策略,因此您在單個函數實現中就不必擔心。
這應該調用std::unexpected
,默認情況下調用std::terminate()
因為拋出的異常不是異常規范的一部分。
(此處適用於Linux上的g ++,Solaris上的
Sun
Oracle CC,AIX BTW上的IBM xlC)
如果您安裝了意外的處理程序,它將按您期望的那樣工作:
include <iostream>
#include <exception>
using namespace std;
class C{};
void myunexpected()
{
throw std::bad_exception();
}
void test() throw(std::bad_exception)
{
throw C();
}
int main()
{
try
{
set_unexpected(myunexpected);
test();
} catch(std::bad_exception& e)
{
std::cout << "Caught ";
}
}
按照[except.unexpected],當一個函數拋出其動態異常規范中未列出的異常時,將調用std::unexpected()
。 根據[unexpected.handler], std::unexpected()
的默認實現只是調用std::terminate()
。
但是,程序可以安裝自己的處理程序,該處理程序可以(重新)引發異常。 如果由此引發的異常不會被動態異常規范允許,它可以被替換std::bad_exception
是允許的時候。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.