Структурная обработка исключений (SEH) [47] реализована и в Visual С++ .NET 2003 [45] и в С++ Builder 6 [49] как расширение стандартного языка С++. Поддержка SEH обеспечивается операционной системой Windows, поэтому программы, в которых используется SEH, непереносимы. Кроме того, при структурной обработке исключений не выполняется вызов деструкторов — это наиболее важное отличие SEH от стандартного механизма. Поэтому Microsoft не рекомендует смешивать стандартные и структурные исключения в одной программе.
Структурная обработка исключений предоставляет две возможности: обработку исключений try...except и обработку завершения try...f inally. Обработка завершения проще, поэтому начнем с нее. В системе Visual C++.NET 2003 синтаксис обработчика завершения выглядит так:
__try {}// защищенный блок
_finally {}// блок завершения
Ключевые слова _try и _f inally пишутся с двумя подчеркиваниями — обычно в системе Visual C++.NET 2003 так обозначаются все расширения стандартного языка С++.
Обработчик завершения гарантирует, что блок завершения будет выполнен при любой попытке выхода из защищенного блока — независимо от способа выхода. Выход из блока _try осуществляется одним из следующих способов:
• нормальное выполнение всех операторов блока от начала до конца;
• возникновение исключения во время выполнения операторов блока;
• выполнение одного из операторов перехода (break, continue, goto, return), хотя этого в [47] рекомендуется избегать.
Поведение Программы после выполнения финального блока зависит от способа выхода из блока _try. Если в финальном блоке нет никаких операторов перехода и он выполняется до конца, то далее в соответствии со способом выхода из защищенного блока происходит следующее:
• выполняются операторы после финального блока;
• выполняется оператор перехода, который вызвал выход из защищенного блока. Синтаксис обработчика исключений выглядит так:
_try {}// защищенный блок
__except (фильтр) {}// блок обработки исключения
Обратите внимание, что в SEH после защищенного блока следует единственный обработчик: это либо обработчик завершения, либо обработчик исключения. Несколько обработчиков писать нельзя, тем более нельзя писать несколько разных обработчиков. Однако разрешается конструкцию try...f i nally вкладывать в блок try...except и наоборот, уровень вложенности не ограничен. Правда, в этом случае существует опасность «запутаться» в порядке выполнения блоков _except и _finally.
При нормальном ходе выполнения программы (когда исключения не возникает) после выполнения операторов защищенного блока блок-обработчик пропускается, и программа продолжает работу со следующего после него оператора. А вот если при выполнении операторов защищенного блока возникло исключение, то обработка его зависит от фильтра.Фильтр — это выражение (в том числе вызов функции), которое должно принимать одно из трех возможных значений:
Очень часто эти константы задаются в качестве фильтра непосредственно. Только последний вариант означает собственно обработку исключения: выполняются операторы блока обработки, после чего управление передается на первый оператор1 после него.
Если результат вычисления фильтра равен первой константе, то исключение отклоняется (exception is dismissed). Код в обработчике прерываний никогда не выполняется. Управление возвращается в точку возникновения прерывания1 и делается попытка снова выполнить ту же инструкцию, которая вызвала исключение.
На первый взгляд поведение не совсем логичное, ведь снова возникнет исключение. Однако не будем забывать, что фильтр — это выражение. Это означает, что на месте фильтра может быть задано несколько выражений через запятую. В этих выражениях можно исправить причину, вызвавшую исключение. Если необходимо выполнить более сложную работу, то в качестве фильтра может быть прописан вызов функции. Функция может получить в качестве параметров любые переменные из защищенного блока, выполнить с ними нужную работу и возвратить константу EXCEPTION_CONTINUE_EXECUTION в качестве результата. Например, если произошло деление на нуль, то функция может изменить значение делителя и программа «похромает» дальше.
Фильтр EXCEPTION_CONTINUE_SEARCH по своему действию похож на оператор throw без аргумента, то есть он «отправляет исключение дальше». Код в обработчике с таким фильтром не выполняется никогда. И только третий вид фильтра обеспечивает выполнение тела обработчика.
Опубликовал Kest
November 13 2013 23:28:15 ·
0 Комментариев ·
5193 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.