C++ 当抛出意外异常时,为什么该程序没有中止?

C++ 当抛出意外异常时,为什么该程序没有中止?,c++,exception,abort,C++,Exception,Abort,我正在阅读《C++常见问题解答》第二版,常见问题解答9.04-什么是异常规范? 这里提到,如果我们从其签名指定一组预定义异常类型的函数中抛出意外异常,则应该调用unexpected()->terminate()->abort()。 但是我的程序捕捉到了意外的异常并且没有中止它,为什么 #include<iostream> using namespace std; class Type1{}; class Type2{}; class Type3{}; void func() th

我正在阅读《C++常见问题解答》第二版,常见问题解答9.04-什么是异常规范?

这里提到,如果我们从其签名指定一组预定义异常类型的函数中抛出意外异常,则应该调用
unexpected()->terminate()->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;
    }
}
#包括
使用名称空间std;
类Type1{};
类类型2{};
类别类型3{};
void func()抛出(类型1,类型2)
{
抛出类型3();
}
int main()
{
试一试{
func();
}
锁扣(类型1和obj1)
{
不能

如果该函数引发的异常类型未在其 异常规范,调用函数std::unexpected

因此,VS2013似乎不符合本节的要求。

来自MSDN:

除PULL()之外的函数异常说明符被解析但未使用。这不符合ISOC++规范第15.4条< /P>

VisualC++是不遵循标准(引用标准中)的。 编辑:关于子问题“为什么没有?”我试图从评论中总结所说的内容

  • 首先,商业编译器总是要面对成本/收益比。如果实现一个功能的成本(直接或间接)高于它的价值(直接或间接),那么它很有可能不会实现(至少很快)在我看来,这是一个重要的考虑因素,一个小功能可能会影响编译器的复杂性和性能(也可以阅读许多C#帖子中关于这个主题的一篇)
  • 实现功能可能会对性能产生很大影响(这似乎是本例中的原因,请参阅)
  • 某些规范不清楚和/或存在漏洞。另请参阅
  • 更改某些内容可能会破坏现有代码。这些破坏性的更改总是要认真考虑的(特别是如果它们在编译时而不是在运行时破坏任何内容)。何时可能发生这种情况?例如:
    • 编译器引入了一种语言扩展,并在以后的标准中声明了一些不同的东西
    • 规范不清楚,或者留下了具体实现的细节
    • 规范实现中的编译器错误已被很好地设置。例如,当Microsoft重写C#编译器时,Roslyin实现必须在旧编译器中重现错误。另请参阅关于中断更改(他们并没有做所有事情)
  • 有些功能(如本例中的功能)对代码没有什么价值,在商业化实现之前(例如,别忘了MSVC++的更新频率低于GCC),它们已被弃用,因此不需要支持它们

    • 正如阿德里亚诺·雷佩蒂所说,众所周知,MSVC忽略了异常规范。但这有一些原因

      这就解释了异常规范解释了编译器不能在编译时强制执行异常控制,必须生成代码才能在运行时控制它。这就是为什么编译器(尤其是MSVC)对它的支持很差的原因

      它引用了一篇非常详细的文章,其结论是:

      因此,以下是我们社区迄今为止所学到的最好的建议:

      • 寓意1:永远不要编写异常规范
      • 寓意二:可能除了一个空的,但如果我是你,我甚至会避免

      VC++不遵循标准有什么好处?很难回答,这种情况经常发生。我不知道这种情况,但通常是:更快的编译(需要做的事情和检查的事情更少),更简单的编译器(原因相同),与其他已经存在的东西冲突,没有成本效益(实现该功能的成本高于其好处),降低生成代码的性能(引入它是无效的)@查询:编写一个不符合编译程序的编译器更容易:-)异常规范也被禁止在C++中,所以现在没有添加它们的必要性。我确信MS看到了这一点,并决定不值得实现一个即将从标准中删除的特性。是的,但我不认为这是他们的问题。产品成本/效益比是主要的,对每个人来说,性能往往是最高的。请看Serge对此的推理。同时,现实世界的使用使他们认为,由于这一(现已被放弃的)功能,降低性能不是首要任务。@Inqutive:您学习了错误的语言。C++03已经死了,您应该学习C++14(或至少是C++11)。自异常规范以来,该标准有两次重大更新。删除它的原因是因为它基本上没有用(除了非抛出规范,该规范被显式替换为
      noexcept
      ),幸运的是有(编译时已检查)
      noexcept
      第二种情况现在开始。