发生异常时析构函数的调用顺序

时间:2019-07-15 18:30:36

标签: c++ exception destructor

在C ++ 20 Standard(14异常处理,14.2构造函数和析构函数)中,有以下示例显示了被调用析构函数的顺序

struct A { };
struct Y { ~Y() noexcept(false) { throw 0; } };
A f() {
   try {
      A a;
      Y y;
      A b;
      return {}; // #1
   } catch (...) {
   }
   return {}; // #2
}

给出以下说明。

  

在#1处,构造了返回的A型对象。然后,本地   变量b被销毁(8.6)。接下来,局部变量y为   破坏,导致堆栈展开,导致破坏   返回的对象,然后销毁局部变量   一种。最后,返回的对象在#2处再次构造

我使用gcc编译器HEAD 10.0.0 20190运行此示例(稍有更改)。

您在这里。

#include <iostream>

struct A
{
    static size_t n;

    A() : id( ++n )
    {
        std::cout << "A( " << id << " )\n";
    }

    A( const A & ) : id( ++n )
    {
        std::cout << "A( " << id << " )\n";
    }

    ~A()
    {
        std::cout << "~A( " << id << " )\n";
    }

    size_t id;
};

size_t A::n;

struct B
{
    B()
    {
        std::cout << "B()\n";
    }

    ~B() noexcept( false )
    {
        std::cout << "~B()\n";
        throw( 0 );
    }        
};

A f()
{
    try
    {
        A a1;
        B b;
        A a2;

        return {};
    }
    catch( ... )
    {
    }

    return {};
}

int main()
{
    f();    
}

程序输出为

A( 1 )
B()
A( 2 )
A( 3 )
~A( 2 )
~B()
~A( 1 )
A( 4 )
~A( 4 )

我看不到行~A( 3 )在哪里。

是编译器错误还是我错过了什么?

0 个答案:

没有答案