当抛出意外异常时,为什么不中止这个程序?
Why is this program not getting aborted when an unexpected exception is thrown?
我正在浏览C++ FAQ 2nd Edition, FAQ 9.04- What is an exception specification?
这里提到,如果从签名指定了一组预定义异常类型的函数抛出意外异常,则应该调用unexpected()->terminate()->abort()
。但是我的程序捕获了意想不到的异常,而不是abort()
,为什么?
#include<iostream>
using namespace std;
class Type1{};
class Type2{};
class Type3{};
void func() throw(Type1, Type2)
{
throw Type3();
}
int main()
{
try{
func();
}
catch (Type1 &obj1)
{
cout << "Type1 is caught" << endl;
}
catch (Type2 &obj2)
{
cout << "Type2 is caught" << endl;
}
catch (Type3 &obj3)
{
cout << "Type3 is caught" << endl;
}
}
这里我得到了本不应该发生的输出Type3 is caught
。
IDE: VS2013
正如Adriano Repetti所说,众所周知,MSVC会忽略异常规范。但这是有原因的。
来自SO的另一篇文章解释了异常规范解释了编译器不能在编译时强制异常控制,必须在运行时生成代码来控制它。这就是为什么编译器(尤其是MSVC)对它的支持很差。
它引用了GOTW的一篇非常详细的文章,结论是:
所以这似乎是我们作为一个社区迄今为止学到的最好的建议:
- 道德#1:永远不要写异常说明
- 寓意#2:除了可能是空的,但如果我是你,我甚至会避免。
From MSDN:
解析除throw()以外的函数异常说明符,但不使用。这不符合ISO c++规范第15.4节
Visual c++根本不遵循标准(引用Mohit的回答中的标准)。
EDIT:关于子问题"why it doesn't?"我试着从评论中总结已经说过的话。
- 首先,一个商业编译器总是要面对成本/收益比率。如果执行一个功能的成本(直接或间接)超过了它的价值(直接或间接),那么很有可能它不会被执行(至少很快)。在我看来,这是一个重要的考虑因素,一个小的特性可能会影响编译器的复杂性和性能(也可以阅读Eric Lippert关于这个主题的许多c#帖子之一)。
- 实现一个功能可能会极大地影响性能(这似乎是在这种情况下的原因,参见Serge的回答)。
- 一些规格不清楚和/或有bug。参见嵌套类的意义是什么? 更改某些东西可能会破坏现有代码。这些破坏性的更改总是要认真考虑的(特别是如果它们不会在编译时破坏任何东西,而是在运行时)。这可能在什么时候发生?例如:
- 编译器引入了一种语言扩展,并在以后的标准中声明了一些不同的东西。
- 规范不明确,或者他们留下了具体的实现细节。
- 规范实现中的编译器错误已经建立良好的。例如,当微软重写c#编译器时,Roslyin的实现不得不重现旧编译器中的错误。另请参阅SLaks关于突破性更改的博客(他们并没有为所有做这件事)。
- 一些特性(比如在这个例子中)给你的代码增加了很少的价值,在它们被商业实现之前(不要忘记msvc++的更新频率比GCC要低,例如),它们被弃用了,那么就没有必要支持它们。
From except_spec
如果函数抛出的异常类型不在其异常规范,调用函数std::unexpected。
所以看起来VS2013不符合这个部分
相关文章:
- 为什么我的 c++ 程序检查不是初始化的变量?
- 为什么Qt Creator的应用程序输出不能从spdlog记录器打印
- 我的程序运行良好,可以复制对象,但是当我使用复制分配(=)时,它仍然可以正常运行.为什么不给错误
- 为什么 For 循环中的 While 循环在我的程序中不起作用?
- 为什么 std::cin.clear() 在这个简单的程序中不起作用?
- 为什么不 垃圾值 正在由该程序打印
- C++简单的程序 - 为什么我的"res"不进入我的向量?创建一个接受输入 (4+44-67+235) 并输出结果的程序
- 额外的反斜杠字符不会影响我的程序.为什么
- 为什么我的程序内存不释放?
- 为什么连VS调试器外启动的程序都不能调用terminate方法呢
- 为什么不将.cpp转换为c程序文件呢
- 为什么应用程序找不到这个libSDL2_image-2.0.so.0库?-Ubuntu 14.04
- 为什么VC++ 2010 Express在这个程序中不需要stdio.h,而gcc++需要?
- 为什么QT QNetworkAccessManager示例在我的程序中不起作用
- 为什么main在visual studio上的win32 c++应用程序中不能解析为符号?
- 为什么find_if在我的程序中不起作用
- 为什么c++应用程序可能不正确地计算表达式
- 为什么不使用空自动PTR不会终止程序?
- 为什么不能跨程序集删除指针?
- 当抛出意外异常时,为什么不中止这个程序?