#cpp #исключения
Имеется в наличии невероятно простой код: #includeclass C { public : C() try { throw std::runtime_error("C::C"); } catch (...) { } }; int main() { C c; } Компилируем этот код компилятором MinGW-builds 8.1.0 x86_64 SJLJ и, запустив полученное приложение, получаем следующий вывод: terminate called after throwing an instance of 'std::runtime_error' what(): C::C This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. А теперь сделаем то же самое, заменив компилятор на MinGW-builds 8.1.0 x86_64 SEH. С удивлением наблюдаем, что строка с сообщением о типе исключения исчезла: This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. Собственно, вопрос. Почему? Что происходит? Так и должно быть или я чего-то не понимаю? P.S. Интересно, что если у конструктора убрать function-try-block, т.е. привести его к виду C() { throw std::runtime_error("C::C"); } то вывод при обоих способах обработки исключений идентичный. ДОПОЛНЕНИЕ Если добавить конструктору спецификатор noexcept, то поведение вновь становится одинаковым: C() noexcept try { throw std::runtime_error("C::C"); } catch (...) { }
Ответы
Ответ 1
Формально говоря, у вас в коде нет "обработки" исключений. Исключение, пойманное function-try-block конструктора, невозможно "подавить" - оно все равно будет перевыброшено автоматически, если вы этого не сделаете сами. То есть в любом из ваших вариантов исключение остается необработанным. Если исключение не обработано, то вызывается std::terminate, которая вызовет текущий обработчик terminate (terminate handler). А что делает установленный по умолчанию обработчик terminate - определяется реализацией. Вот эти различия между реализациями вы и наблюдаете. Например, если в GCC при помощи std::set_terminate задать свой пустой обработчик terminate, то вывод о типе исключения и вывод what() исчезнет.
Комментариев нет:
Отправить комментарий