Почему вызывается terminate (), даже если непредсказатель () генерирует указанное исключение? - PullRequest
1 голос
/ 06 ноября 2011

Рассмотрим код ниже:

#include <iostream>
#include <exception>

void third_party_function() throw () {
    throw -1; // oops
}

void recover() throw (std::exception) {
    std::cout << "We will throw std::exception() to avoid terminate() to be called.\n";
    throw std::exception();
}

int main(int argc, char** argv) {
    try {
        std::set_unexpected(recover);
        third_party_function();
    } catch (std::exception e) {
         std::cout << "Unexpected exception: " << e.what() << '\n';
    }
    return 0;
}

Это вывод из программы:

Мы сгенерируем std :: exception (), чтобы не вызывать terminate (). прекращение вызова после выброса экземпляра 'std :: exception'
что (): std :: исключение

Я не понимаю, почему в любом случае вызывается terminate () (поэтому никогда не перехватывается исключение std ::), несмотря на то, что я сделал то, что предлагает Страуструп, с аналогичным примером, чтобы избежать вызова terminate () после вызова обработчика (см. язык программирования C ++, 3-е издание, глава 14.6)

Ответы [ 2 ]

2 голосов
/ 06 ноября 2011

third_party_function обещает не генерировать никаких исключений.

Таким образом, любое исключение типа int или std::exception не имеет значения, вызывает вызов std::terminate для каждого C++ 98 §15.5.2 / 2.

Если бы вместо этого он ограничился std::bad_exception, то при соответствующей реализации новое исключение будет автоматически переведено в std::bad_exception.

В текущем стандарте C ++ 11 использование такого рода спецификации исключений с использованием ключевого слова throw не рекомендуется.

C ++ 11, однако, имеет ту же формулировку, что и C ++ 98 относительноэффект, в C ++ 11 §15.5.2 / 3.

Также обратите внимание, что хотя Visual C ++ допускает синтаксис, он никогда не учитывал семантику (за исключением, возможно, nothrow, который теперь задокументирован как эквивалентный).к использованию языкового расширения, которое не говорит об исключениях).

Таким образом, несмотря на то, что оно все еще действует в стандарте C ++, на практике оно непереносимо, если для спецификаций исключений используется какой-либо конкретный эффект, кроме nothrow.

Cheers & hth.,

1 голос
/ 06 ноября 2011

Идея состоит в том, чтобы неожиданный обработчик генерировал исключение в списке спецификаций исключений.Поскольку спецификация third_party_function не создает исключений, она не будет работать.Однако, если third_party_function имеет std::exception в спецификации исключений, ваш код будет работать.

Спецификации исключений устарели в C ++ 11, возможно, вам не следует их использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...