инструкция try-except
Инструкция try-except
— это расширение, которое поддерживает структурированную обработку исключений на языках C и C++.
// . . .
__try {
// guarded code
}
__except ( /* filter expression */ ) {
// termination code
}
// . . .
грамматики
try-except-statement
:
__try
compound-statement
__except (
expression
)
compound-statement
Замечания
Инструкция try-except
— это расширение Майкрософт на языках C и C++. Он позволяет целевым приложениям управлять событиями, которые обычно завершают выполнение программы. Такие события называются структурированными исключениями или исключениями . Механизм, который касается этих исключений, называется структурированной обработкой исключений (SEH).
Дополнительные сведения см. в инструкции try-finally.
Исключения могут быть либо аппаратными, либо программными. Структурированная обработка исключений полезна, даже если приложения не могут полностью восстановиться из аппаратных или программных исключений. SEH позволяет отображать сведения об ошибках и перехватывать внутреннее состояние приложения, чтобы помочь диагностировать проблему. Это особенно полезно для периодических проблем, которые не легко воспроизвести.
Примечание.
Структурированная обработка исключений поддерживается в Win32 для исходных файлов как на C, так и на C++. Однако он не предназначен специально для C++. Для того чтобы ваш код лучше переносился, лучше использовать механизм обработки исключений языка C++. Кроме того, этот механизм отличается большей гибкостью, поскольку может обрабатывать исключения любого типа. Для программ C++ рекомендуется использовать собственную обработку исключений C++: попробуйте, перехват и вызов инструкций.
Составной оператор после __try
предложения является текстом или защищенным разделом. Выражение __except
также называется выражением фильтра . Его значение определяет, как обрабатывается исключение. Составной оператор после предложения __except
является обработчиком исключения. Обработчик задает действия, выполняемые при возникновении исключения во время выполнения раздела текста. Выполнение происходит следующим образом:
Сначала выполняется защищенный раздел.
Если исключение при этом не возникает, выполнение переходит в инструкцию, стоящую после предложения
__except
.Если исключение возникает во время выполнения защищенного раздела или в любой подпрограмме вызовов защищенного раздела,
__except
выражение вычисляется. Есть три возможных значения :EXCEPTION_CONTINUE_EXECUTION
(-1) Исключение закрывается. Выполнение продолжается в точке, в которой возникло исключение.EXCEPTION_CONTINUE_SEARCH
(0) Исключение не распознано. Продолжайте поиск по стеку обработчика, сначала для содержащихtry-except
операторов, а затем обработчиков со следующим самым высоким приоритетом.EXCEPTION_EXECUTE_HANDLER
(1) Исключение распознается. Перенесите управление в обработчик исключений, выполнив__except
составную инструкцию, а затем продолжайте выполнение после__except
блока.
Выражение __except
вычисляется как выражение C. Оно ограничено одним значением, оператором условного выражения или оператором запятой. Если требуется более сложная обработка, выражение может вызывать процедуру, которая возвращает одно из этих трех значений.
Каждое приложение может иметь свой собственный обработчик исключений.
Это недопустимо, чтобы перейти к оператору __try
, но допустимо, чтобы выскочить из одного. Обработчик исключений не вызывается, если процесс завершается в середине выполнения try-except
инструкции.
Для совместимости с предыдущими версиями _try, _except и _leave являются синонимами для __try
, __except
и __leave
если параметр компилятора /Za (Отключить расширения языка) не указан.
Ключевое слово __leave
.
__leave
Ключевое слово допустимо только в защищенном разделе try-except
инструкции, и его эффект заключается в переходе к концу защищенного раздела. Выполнение продолжается с первого оператора, следующего за обработчиком исключений.
Оператор goto
также может выскочить из защищенного раздела, и он не снижает производительность, как это делает в инструкции try-finally . Это связано с тем, что очистка стека не происходит. Однако рекомендуется использовать ключевое __leave
слово, goto
а не оператор. Причина заключается в том, что вы, скорее всего, сделаете ошибку программирования, если защищенный раздел большой или сложный.
Структурированные функции обработки исключений
Структурированная обработка исключений предоставляет две встроенные функции, доступные для использования с try-except
инструкцией: GetExceptionCode и GetExceptionInformation.
GetExceptionCode
возвращает код (32-разрядное целое число) исключения.
Встроенная функция GetExceptionInformation
возвращает указатель на структуру EXCEPTION_POINTERS , содержащую дополнительные сведения об исключении. Через этот указатель можно обращаться к состоянию компьютера, которое существовало в момент возникновения аппаратного исключения. Его структура выглядит следующим образом.
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
Типы PEXCEPTION_RECORD
указателей и PCONTEXT
определены в файле include <winnt.h> и _CONTEXT
_EXCEPTION_RECORD
определены в файле include <excpt.h>
Вы можете использовать GetExceptionCode
в обработчике исключений. Однако можно использовать GetExceptionInformation
только в выражении фильтра исключений. Информация, на которую она указывает, обычно находится в стеке и больше не доступна, когда элемент управления передается обработчику исключений.
Встроенная функция AbnormalTermination доступна в обработчике завершения. Возвращает значение 0, если текст инструкции try-finally завершается последовательно. В остальных случаях функция возвращает 1.
<Excpt.h> определяет некоторые альтернативные имена для этих встроенных элементов:
GetExceptionCode
— это эквивалент _exception_code
GetExceptionInformation
— это эквивалент _exception_info
AbnormalTermination
— это эквивалент _abnormal_termination
Пример
// exceptions_try_except_Statement.cpp
// Example of try-except and try-finally statements
#include <stdio.h>
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
puts("in filter.");
if (code == EXCEPTION_ACCESS_VIOLATION)
{
puts("caught AV as expected.");
return EXCEPTION_EXECUTE_HANDLER;
}
else
{
puts("didn't catch AV, unexpected.");
return EXCEPTION_CONTINUE_SEARCH;
};
}
int main()
{
int* p = 0x00000000; // pointer to NULL
puts("hello");
__try
{
puts("in try");
__try
{
puts("in try");
*p = 13; // causes an access violation exception;
}
__finally
{
puts("in finally. termination: ");
puts(AbnormalTermination() ? "\tabnormal" : "\tnormal");
}
}
__except(filter(GetExceptionCode(), GetExceptionInformation()))
{
puts("in except");
}
puts("world");
}
Выходные данные
hello
in try
in try
in filter.
caught AV as expected.
in finally. termination:
abnormal
in except
world
См. также
Написание обработчика исключений
Structured Exception Handling (C/C++)
Ключевые слова