[英]Why bad_exception is not thrown automatically?
Why doesn't this piece of code run without error? 为什么这段代码没有错误运行? Isn't
bad_exception
supposed to be called automatically when an unexpected exception is encountered? 遇到意外异常时,难道不应该自动调用
bad_exception
吗? Or is it necessary to set a handler for it? 还是有必要为其设置处理程序?
#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 ";
}
}
In C++03 theory: If you throw an exception that is not in the exception specification, unexpected()
gets called. 在C ++ 03理论中:如果引发的异常不在异常规范中,则将调用
unexpected()
。 If you have not set the unexpected handler via set_unexpected()
this means terminate()
gets called which is the case you observed. 如果您尚未通过
set_unexpected()
设置意外的处理程序, set_unexpected()
这意味着您将观察到terminate()
被调用的情况。 If you have set an unexpected handler that does not call terminate but throws an exception, and if that exception is not listed in your exception specification, it gets translated into bad_exception. 如果您设置一个意想不到的处理程序不调用终止,但抛出一个异常,如果该异常不能在你的异常规范中列出,它被翻译成bad_exception。 So in order to get the expected result, call
set_unexpected()
first with an appropriate handler. 因此,为了获得预期的结果,请首先使用适当的处理程序调用
set_unexpected()
。
In C++03 practice: Some compilers do not support exception specifications at all (other than throw()
), others just don't evaluate/check them for correctness. 在C ++ 03的实践中:有些编译器根本不支持异常规范(
throw()
除外),其他编译器只是不评估/检查其正确性。 As Herb Sutter points out , exception specifications create a clumsy "shadow type system" that is not easy to handle right (if it is possible at all). 正如Herb Sutter指出的那样 ,异常规范创建了一个笨拙的“影子类型系统”,该系统很难正确处理(如果可能的话)。 Therefore..
因此..
... in C++11: Exception specifications are deprecated . ...在C ++ 11中: 不赞成使用 Exception规范。 You should rather not use them.
您宁可不要使用它们。 However, there is a
nothrow
operator that has a slightly different functionality than throw()
但是,有一个
nothrow
运算符的功能与throw()
略有不同
PS: so why have std::bad_exception in C++03? PS:那么为什么C ++ 03中有std :: bad_exception? You hav three different regions of code:
您拥有三个不同的代码区域:
So if the "foreign" code throws an exception that violates your exception specification, you have three possible outcomes of that: 因此,如果“外来”代码引发了违反您的异常规范的异常,则可能会产生以下三种结果:
Setting your own handler inside the function disables any handler that was previously set by anyone else who just wants to use your function. 在函数内设置自己的处理程序将禁用任何其他仅想使用您的函数的人先前设置的处理程序。 He will not expect you to disable his handler.
他不会期望您禁用他的处理程序。 Besides, the handler is meant as a global what-happens-if policy and thus is nothing you should care about in a single function implementation.
此外,该处理程序是一种全局的“假设-如果”策略,因此您在单个函数实现中就不必担心。
This should call std::unexpected
which by default call std::terminate()
as the thrown exception isn't part of the exception specification. 这应该调用
std::unexpected
,默认情况下调用std::terminate()
因为抛出的异常不是异常规范的一部分。
(It does here with g++ on Linux,
Sun
Oracle CC on Solaris, IBM xlC on AIX BTW) (此处适用于Linux上的g ++,Solaris上的
Sun
Oracle CC,AIX BTW上的IBM xlC)
If you install an unexpected handler, it works as you expect here: 如果您安装了意外的处理程序,它将按您期望的那样工作:
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 ";
}
}
As per [except.unexpected], when a function throws an exception not listed in its dynamic exception specification, std::unexpected()
is called. 按照[except.unexpected],当一个函数抛出其动态异常规范中未列出的异常时,将调用
std::unexpected()
。 According to [unexpected.handler], the default implementation of std::unexpected()
simply calls std::terminate()
. 根据[unexpected.handler],
std::unexpected()
的默认实现只是调用std::terminate()
。
However, the program can install its own handler, which can (re-)throw an exception. 但是,程序可以安装自己的处理程序,该处理程序可以(重新)引发异常。 If the exception thus thrown is not allowed by the dynamic exception specification, it can be replaced by
std::bad_exception
when that is allowed. 如果由此引发的异常不会被动态异常规范允许,它可以被替换
std::bad_exception
是允许的时候。
Your catch-block would only catch exceptions of the type bad_exception
, or a subtype thereof. 您的catch块将仅捕获
bad_exception
类型或其子类型的异常。 C
does not meet this criterion. C
不符合此条件。
Actually, this question is very similar to yours. 实际上, 这个问题与您的问题非常相似。 The accepted answer explains that if your function throws an exception that does not match the specification (if there is any), then
std::unexpected
is called, which by default calls std::terminate
. 可接受的答案说明,如果您的函数抛出与规范不匹配的异常(如果存在),则将调用
std::unexpected
,默认情况下将调用std::terminate
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.