Поделиться через


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

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

Пример 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 для проверки типа исключения перед выполнением обработчика. Это позволяет системе продолжать поиск соответствующего обработчика, если возникает другое исключение.

Кроме того, использование инструкции возврата в блоке __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 
    } 
}