Использование обработчика исключений
В следующих примерах показано использование обработчика исключений.
Пример 1
Следующий фрагмент кода использует структурированную обработку исключений для проверка, приведет ли операция деления к двум 32-разрядным целым числам, что приведет к ошибке деления по нулю. Если это происходит, функция возвращает ЗНАЧЕНИЕ FALSE, в противном случае возвращает значение TRUE.
BOOL SafeDiv(INT32 dividend, INT32 divisor, INT32 *pResult)
{
__try
{
*pResult = dividend / divisor;
}
__except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
return FALSE;
}
return TRUE;
}
Пример 2
В следующем примере функция вызывает функцию DebugBreak и использует структурированную обработку исключений для проверка для исключения точки останова. Если это происходит, функция возвращает ЗНАЧЕНИЕ FALSE, в противном случае возвращает значение TRUE.
Выражение фильтра в примере использует функцию GetExceptionCode для проверка тип исключения перед выполнением обработчика. Это позволяет системе продолжать поиск соответствующего обработчика, если возникает другое исключение.
Кроме того, использование инструкции return в блоке __try обработчика исключений отличается от использования возврата в блоке __try обработчика завершения, что приводит к ненормальному завершению блока __try. Это допустимое использование инструкции return в обработчике исключений.
BOOL CheckForDebugger()
{
__try
{
DebugBreak();
}
__except(GetExceptionCode() == EXCEPTION_BREAKPOINT ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
// No debugger is attached, so return FALSE
// and continue.
return FALSE;
}
return TRUE;
}
Возвращается только EXCEPTION_EXECUTE_HANDLER из фильтра исключений, если ожидается тип исключения и известный адрес сбоя. Необходимо разрешить обработчику исключений по умолчанию обрабатывать непредвиденные типы исключений и адреса сбоя.
Пример 3
В следующем примере показано взаимодействие вложенных обработчиков. Функция RaiseException вызывает исключение в защищенном теле обработчика завершения, который находится внутри защищенного тела обработчика исключений. Исключение приводит к тому, что система вычисляет функцию FilterFunction, возвращаемое значение в свою очередь приводит к вызову обработчика исключений. Однако перед выполнением блока обработчика исключений __finally обработчика завершения выполняется, так как поток управления оставил блок __try обработчика завершения.
DWORD FilterFunction()
{
printf("1 "); // printed first
return EXCEPTION_EXECUTE_HANDLER;
}
VOID main(VOID)
{
__try
{
__try
{
RaiseException(
1, // exception code
0, // continuable exception
0, NULL); // no arguments
}
__finally
{
printf("2 "); // this is printed second
}
}
__except ( FilterFunction() )
{
printf("3\n"); // this is printed last
}
}