Похоже, что в современных версиях хотя бы некоторых компиляторов (GCC 5.2 и Visual С++ 2015 Update 1) некорректно генерировать конструкторы по умолчанию noexcept
, когда есть инициализированные члены класса:
#include <memory>
#include <exception>
#include <iostream>
struct E {};
struct A
{
A()
{
throw E();
}
};
struct B
{
A a;
};
struct C
{
std::shared_ptr<B> b{ std::make_shared<B>() };
//C() {} // uncomment to fix
};
int main()
{
try
{
new C;
}
catch (const E &)
{
std::cout << "Exception caught\n";
}
std::cout << "Exiting...\n";
}
Запуск этого кода вызывает вызов std::terminate
(вместо вызова блока catch) в GCC 5.2 (режим С++ 14) и обновление Visual С++ 2015 1.
Живой пример: http://coliru.stacked-crooked.com/view?id=16efc34ec173aca7
Uncommenting пустой конструктор исправляет этот код для Visual С++, но не для GCC. Clang 3.6 правильно (я полагаю?) Вызывает блокировку catch в любом случае.
Существуют ли какие-либо правила в стандарте, которые указывают, когда созданный по умолчанию конструктор должен быть помечен как noexcept
?