Condividi tramite


Uso di un gestore di eccezioni

Negli esempi seguenti viene illustrato l'uso di un gestore eccezioni.

Alcuni esempi usano la funzione GetExceptionCode all'interno dell'espressione di filtro __except per controllare il tipo di eccezione prima di eseguire il gestore. Ciò consente al sistema di continuare la ricerca di un gestore appropriato se si verifica un altro tipo di eccezione.

In generale, restituisce solo EXCEPTION_EXECUTE_HANDLER da un filtro eccezioni quando è previsto il tipo di eccezione e l'indirizzo di errore è noto. È consigliabile consentire al gestore eccezioni predefinito di elaborare tipi di eccezione imprevisti e indirizzi di errore.

Esempio 1

Il frammento di codice seguente usa la gestione strutturata delle eccezioni per verificare se un'operazione di divisione su due interi a 32 bit genererà un errore di divisione per zero. In questo caso, la funzione restituisce FALSE; in caso contrario, restituisce 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;
} 

Esempio 2

La seguente funzione di esempio chiama la funzione DebugBreak e utilizza la gestione strutturata delle eccezioni per verificare un'eccezione di punto di interruzione. In caso affermativo, significa che l'eccezione non è stata gestita da un debugger e la funzione restituisce FALSE; in caso contrario, restituisce TRUE.

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;
}

Esempio 3

Nell'esempio seguente viene illustrata l'interazione dei gestori annidati. La funzione RaiseException provoca un'eccezione nel corpo sorvegliato di un gestore di terminazione che si trova all'interno del corpo sorvegliato di un gestore delle eccezioni. L'eccezione fa sì che il sistema valuti la funzione FilterFunction, il cui valore restituito a sua volta fa sì che venga richiamato il gestore eccezioni. Tuttavia, prima dell'esecuzione del blocco del gestore delle eccezioni, viene eseguito il blocco __finally del gestore di terminazione perché il flusso di controllo è uscito dal blocco __try del gestore di terminazione.

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 
    } 
}