Что касается разворачивания стека, в стандарте С++ говорится:
Исключение считается неотображенным после завершения инициализации объекта исключения ([except.throw]) до завершения активации обработчика исключения ([except.handle]). Это включает разматывание стека.
на par 15.5.3 текущего стандарта. Я пытался понять, к чему относится последнее предложение (This includes stack unwindings
):
- Предполагается, что компилятор должен позаботиться о разматывании стека?
- или, если он говорит, что он зависит от компилятора, нужно ли разматывать или нет стек?
Вопрос возникает из следующего фрагмента:
#include <iostream>
#include <exception>
struct S{
S() { std::cout << " S constructor" << std::endl; }
virtual ~S() { std::cout << " S destructor" << std::endl; }
};
void f() {
try{throw(0);}
catch(...){}
}
void g() {
throw(10);
}
int main() {
S s;
f();
//g();
}
Теперь:
- если вы запустили его как-есть (поймать исключение), у вас есть подсказка об отказе стека
- если вы прокомментируете
f();
и раскомментируетеg();
(не перехватывая исключение), у вас есть намек на то, что стек не развязан
Итак, оба эксперимента, похоже, в пользу первой пули выше; как clang++, так и g++ соглашаются на результат (но это не дискриминант).
Кроме того, мне очень странно, что стандарт, который очень осторожен в определении времени и продолжительности объекта, оставляет здесь тень.
Может кто-нибудь уточнить? Развертывание стека для исключенных исключений, гарантированных стандартом? Если да, то где? Если нет, то почему?