![](/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.