Компилятор
C++ 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 {}; // #1
}
catch( ... )
{
}
return {}; // #2
}
int main()
{
f();
}
В этой программе деструктор структуры
B выбрасывает исключение. В связи с этим должен удаляться объект структуры
A, созданный в строке, помеченной как
#1, так как происходит очищение стека от локальных объектов прежде, чем управление передасться на предложение с
catch.
однако этого не происходит. Вывод программы следующий:
A( 1 )
B()
A( 2 )
A( 3 )
~A( 2 )
~B()
~A( 1 )
A( 4 )
~A( 4 )
Хотя на самом деле в соответствии со стандартом C++ вывод на консоль должен выглядеть как
A( 1 )
B()
A( 2 )
A( 3 )
~A( 2 )
~B()
~A( 3 )
~A( 1 )
A( 4 )
~A( 4 )
То есть между строками
~B()
~A( 1 )
должна появиться строка
~A( 3 )
То есть объект, созданный в предложении, помеченном как
#1, остался не удаленным, что ведет к неопределенному поведению программы.
Похоже. этот баг уже давно присутствует в этом компиляторе, возможно, и в других компиляторах.
Так что будьте осторожны, когда используете исключения. Не допускайте подобного кода.