MiddleДебаггингОчень частоЕщё не отвечали
Что произойдёт, если деструктор бросит исключение во время stack unwinding?
Эта программа бросает исключение, и во время последующей очистки деструктор Bad тоже бросает. Вместо какого-либо обработчика процесс резко завершается.
struct Bad {
~Bad() noexcept(false) { throw std::runtime_error("dtor"); }
};
void demo() {
Bad b;
throw std::logic_error("first");
}
Найдите ошибку и объясните причину.
Если деструктор выпускает исключение наружу, пока уже разворачивается другое исключение, программа вызывает std::terminate().
- ✗Помечать деструктор noexcept(false) и надеяться, что вызывающий код всё поймает
- ✗Бросать из cleanup-кода, когда другое исключение уже активно
- ✗Оставлять важную обработку ошибок только в деструкторе
- →Что показывает std::uncaught_exceptions()?
- →Как стандартные контейнеры используют noexcept move-конструкторы?
Деструкторы неявно noexcept начиная с C++11. Если из деструктора вылетает исключение в тот момент, когда уже разворачивается другое, рантайм не может выбрать, какое из двух распространять, и вызывает std::terminate():
struct Bad {
~Bad() noexcept(false) { throw std::runtime_error("dtor"); }
};
void demo() {
Bad b; // деструктор b сработает при раскрутке
throw std::logic_error("первое"); // запускает раскрутку → ~Bad() бросает второе
} // два активных исключения → std::terminate()
Правило: деструкторы не должны бросать. Cleanup, способный завершиться ошибкой, оборачивайте в try/catch внутри самого деструктора и проглатывайте или логируйте ошибку.