使用异常处理程序

以下示例演示异常处理程序的使用。

示例 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 块中使用 return 语句不同于在终止处理程序的 __try 块中使用 return,这会导致 __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 
    } 
}