Использование обработчика исключений

В следующих примерах показано использование обработчика исключений.

Пример 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 
    } 
}