MinGW - SEH и SJLJ. Странное поведение

183
18 сентября 2018, 23:30

Имеется в наличии невероятно простой код:

#include <stdexcept>
class 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 (...) { }
Answer 1

Формально говоря, у вас в коде нет "обработки" исключений. Исключение, пойманное function-try-block конструктора, невозможно "подавить" - оно все равно будет перевыброшено автоматически, если вы этого не сделаете сами. То есть в любом из ваших вариантов исключение остается необработанным.

Если исключение не обработано, то вызывается std::terminate, которая вызовет текущий обработчик terminate (terminate handler). А что делает установленный по умолчанию обработчик terminate - определяется реализацией. Вот эти различия между реализациями вы и наблюдаете.

Например, если в GCC при помощи std::set_terminate задать свой пустой обработчик terminate, то вывод о типе исключения и вывод what() исчезнет.

READ ALSO
Qt сигналы слоты

Qt сигналы слоты

Пытаюсь соединить два объекта путем сигнально-слотового метода, но в итоге выдает ошибки такого рода:

219
Определение классов qt

Определение классов qt

Изучаю qt и столкнулся с таким (обсолютно не понятным для меня) примером:

225
c++ stl: сортировка и копирование

c++ stl: сортировка и копирование

Подскажите пожалуйста, есть ли возможность средствами STL отсортировать вектор в новый вектор?

210
Java выводит already in use: bind, но порт не занят

Java выводит already in use: bind, но порт не занят

Выводит ошибку BindException: Address already in use: bind, хотя порт не занят

198