异常行为C 14 vs C 98

Exception behavior C++14 vs C++98

本文关键字:vs 异常      更新时间:2023-10-16

我写了以下程序

#include <iostream>
#include <stdexcept>
class Myclass
{
    public:
    ~Myclass() 
    {
        //throw std::runtime_error("second (in destructor)");
        throw 1;
    }
};
void fun()
{
    Myclass obj;
}
int main()
{   
    try
    {
        fun();      
    }
    catch (const std::exception& e)
    {
       std::cout << e.what();
    }
    catch(...)
    {
       std::cout << " ... default Catch" << std::endl; 
    }
    std::cout << "Normal" << std::endl;
    return 0;
}  

当我以C++98模式(cpp.sh(上方运行程序时,它会打印

 ... default Catch
Normal

当我使用C++14模式运行它时,它不会打印任何东西。为什么此行为发生变化?

我确实理解,只要发生任何异常,并且任何destructor(在堆栈放松过程中(会引发任何例外,则会终止应用程序。但是这里只有一次来自destructortry块。

以来,由于C 11,没有明确阐明的异常规范具有与默认生成的一个相同的例外规范。在您的情况下,默认生成的破坏者将是 noexcept(最多默认的驱动器是(,因此您的破坏者也被视为 noexcept。从noexcept函数抛出会自动调用std::terminate

如果您希望异常被捕获,请将击曲线声明为投掷:

~Myclass() noexcept(false)
{
    //throw std::runtime_error("second (in destructor)");
    throw 1;
}

但是,在您这样做之前,重新考虑。是一个不好的主意具有投掷破坏者。

抛弃灾难的异常总是一个坏主意,因为如果飞行中已经有一个例外(例如,在堆栈中调用的destructor在放松时称为destructor(std::terminate将被称为。

>

也就是说,C 11向破坏者添加了一个隐式noexcept(true)(下面列出的案例除外(,如果从noexcept(true) Destructor中投掷,则同样是std::terminate

§12.4/3

[class.dtor] [注意:没有NOExcept特定符的攻击子的声明具有相同的例外 规格好像已被隐式声明(15.4(。 - 终注]

和§15.4/14

[exceed.spec] 隐式宣布的驱动器的例外规范,或没有NOExcept特定器的驱动器的例外规范, 当且仅当其任何潜在构造的子项目中的任何破坏者中,都可能进行攻击 可能投掷。

我强烈建议您按顺序重组您的代码不是扔进destructors。