обработка исключений (ограничение исключений) - PullRequest
3 голосов
/ 31 июля 2011

Я имел дело со следующим кодом, и запутался, пожалуйста, посмотрите на него

#include<iostream>
#include<conio.h>
#include<string.h>

using namespace std;

void Xhandler(int test) throw(char,double)  /*i am restricting an integer exception     here by not including it in the argument list of throw*/
{
if(test==0) throw test;
if(test==1) throw 'a';
if(test==2) throw 123.23;
}

int main()
{
cout<"start";

try{
    Xhandler(0);  
}

catch(int i)  /*this catch statement must be ignored then,but it is running*/
{
    cout<<"caught an integer"; /*this is the output on the screen*/
}
catch(char c)
{
    cout<<"caught character";
}
catch(double a)
{
    cout<<"caught double";
}

cout<<"end";
    _getch();
    return 0;

     }

оператор catch, соответствующий int, должен игнорироваться (что не игнорируется), и программа должна быть завершена, так как не осталось соответствующего оператора catch, но это не так?

Ответы [ 4 ]

2 голосов
/ 01 августа 2011

Ну, причина того, что обработчик исключений

catch(int i)  /*this catch statement must be ignored then,but it is running*/
{
    cout<<"caught an integer"; /*this is the output on the screen*/
}

выполняется вместо неожиданного вызываемого обработчика, вероятно, лежит на вашем компиляторе.

Стандартное поведение соответствия, когда исключение выдаетсяфункция со спецификацией исключения, но тип брошенного исключения не соответствует спецификации исключения, будет то, что неожиданный обработчик будет вызван.Обработчик по умолчанию завершает программу.

В действительности многие компиляторы игнорируют спецификации исключений, а некоторые могут просто выдавать некоторые предупреждения, сообщающие вам об этом.То, что компиляторы их игнорируют, - хорошая идея imho.

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

Для получения дополнительной информации о спецификациях исключений и о том, почему их следует избегать, см. здесь (Херб Саттер объясняет там, в основном, что спецификации исключений в C ++ не такие, какими они должны быть / большинство людей думают, что они есть).И вы получите дополнительные ссылки внизу страницы ...

2 голосов
/ 31 июля 2011

Вы не указали компилятор.Если вы используете Microsoft Visual C ++, то на странице Спецификации исключений на MSDN

Visual C ++ отходит от стандарта ANSI при реализации спецификаций исключений.В следующей таблице приведены реализации спецификаций исключений в Visual C ++:

...

throw (type) - функция может генерировать исключение типа type.Однако в Visual C ++ .NET это интерпретируется как throw (...).

При использовании g ++ процесс завершается из-за непредвиденного исключения при выполнении вашего примера.

0 голосов
/ 23 января 2018

Причина такого поведения заключается в следующем: если выброшенное исключение не совпадает в type указанном списке типов исключений, то вызывается std::unexpected().Который далее выбрасывает соответствующий тип исключения на основе того, включен ли std::bad_exception в список типов исключений .

Ниже приводятся выдержки из проекта стандарта C ++ 11 (Номер документа: N3337) :( Хотя проект стандартов не является окончательным стандартом, но здесь он служит цели)

15.4 Спецификации исключений [9]
Всякий раз, когда выдается исключение, и поискобработчик (15.3) встречает самый внешний блок функции с exception-specification, который не допускает исключения, затем, - если exception-specification является dynamic-exception-specification, вызывается функция std::unexpected() (15.5.2), - в противном случае вызывается функция std::terminate() (15.5.1).

[ Example: void f() throw (X, Y) { int n = 0; if (n) throw X(); // OK if (n) throw Z(); // also OK throw W(); // will call std::unexpected() } —end example ]

Следуя определенному отрывку поведению функции std::unexpected():

15.5.2 Функция std::unexpected()
Функция std::unexpected() не должна возвращаться, но она может генерировать (или повторно генерировать) исключение.Если он генерирует новое исключение, которое разрешено спецификацией исключения, которая ранее была нарушена, тогда поиск другого обработчика будет продолжен при вызове функции, спецификация исключения которой была нарушена.Если он выбрасывает или сбрасывает исключение, которое dynamic-exception-specification не разрешает, то происходит следующее: Если dynamic-exception-specification не включает класс std::bad_- exception (18.8.2), то вызывается функция std::terminate(), в противном случае выдаетсяисключение заменяется определенным реализацией объектом типа std::bad_exception, и поиск другого обработчика будет продолжен при вызове функции, чье dynamic-exception-specification было нарушено.Таким образом, dynamic-exception-specification гарантирует, что будут выброшены только перечисленные исключения.Если dynamic-exception-specification включает тип std::bad_exception, то любое исключение, отсутствующее в списке, может быть заменено на std::bad_exception в функции std::unexpected().

0 голосов
/ 01 августа 2011

Ваша подпрограмма Xhandler генерирует исключение int после объявления о том, что она не выбросит int исключения. Это не определено, поэтому может случиться что угодно.

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