Почему эта программа не прерывается при возникновении непредвиденного исключения?

Я шел через C++ FAQ 2nd Edition, FAQ 9.04- What is an exception specification?,

Там упоминается, что если мы сгенерируем непредвиденное исключение из функции, чья сигнатура определяет набор предопределенных типов исключений, она должна вызвать unexpected()->terminate()->abort(),
Но моя программа ловит неожиданное исключение и не abort()И почему?

#include<iostream>
using namespace std;

class Type1{};
class Type2{};
class Type3{};

void func() throw(Type1, Type2)
{
throw Type3();
}

int main()
{
try{
func();
}
catch (Type1 &obj1)
{
cout << "Type1 is caught" << endl;
}
catch (Type2 &obj2)
{
cout << "Type2 is caught" << endl;
}
catch (Type3 &obj3)
{
cout << "Type3 is caught" << endl;
}
}

Здесь я получаю вывод Type3 is caught что не должно было произойти.

IDE: VS2013

7

Решение

Из MSDN:

Спецификаторы исключений функций, кроме throw (), анализируются, но не используются. Это не соответствует разделу 15.4 спецификации ISO C ++

Visual C ++ просто не соответствует стандарту (цитата из стандарта в Ответ Мохита).

РЕДАКТИРОВАТЬ: о подвопросе «почему это не так?» Я пытаюсь обобщить из комментариев то, что было сказано.

  • Прежде всего, коммерческий компилятор должен всегда сталкиваться затрат и выгод соотношение. Если реализация функции будет стоить (прямо или косвенно) больше, чем она стоит (прямо или косвенно), тогда есть хорошие шансы, что она не будет реализована (по крайней мере, в ближайшее время). На мой взгляд, это важное соображение, маленький функция может повлиять на сложность и производительность компилятора (также читайте один из многих Эрик ЛиппертC # сообщения на эту тему).
  • Реализация функции может значительно повлиять на производительность (это кажется причиной в этом случае, см. Сергей ответ).
  • Некоторые спецификации неясны и / или содержат ошибки. Смотрите также Какой смысл вложенных классов?
  • Чтобы что-то изменить, может сломаться существующий код. Эти критические изменения всегда принимаются во внимание (особенно если они ничего не нарушают во время компиляции, но во время выполнения). Когда это может произойти? Например:
    • Компилятор ввел языковые расширения и позже в будущем стандарте утверждает что-то другое.
    • Спецификации были неясны или оставляли детали как специфические для реализации.
    • Ошибки компиляции в реализации спецификаций хорошо estabilished. Посмотрите, например, когда Microsoft переписала C # компилятор, реализация Roslyin должна была воспроизвести ошибки в старом компиляторе. Смотрите также Блог SLaks о нарушении изменений (они не делали этого для все).
  • Некоторые функции (как в этом случае) добавляют мало значения вашему коду, и, прежде чем они будут реализованы на коммерческой основе (не забывайте, например, MSVC ++ обновляется реже, чем GCC), они осуждается тогда нет никакой необходимости поддерживать их.
4

Другие решения

Как сказал Адриано Репетти, MSVC, как известно, игнорирует спецификации исключений. Но для этого есть несколько причин.

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

И это приводит очень подробную статью из GOTW, вывод которого таков:

Итак, вот что кажется лучшим советом, который мы, как сообщество, получили на сегодняшний день:

  • Мораль № 1: Никогда не пишите спецификацию исключений.
  • Мораль № 2: За исключением, возможно, пустого, но на вашем месте я бы избегал даже этого.
6

От except_spec

Если функция выдает исключение типа, не указанного в ее
В спецификации исключений вызывается функция std :: непредвиденный.

Похоже, что VS2013 не соответствует этому разделу.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector