Condividi tramite


Uso di un gestore di eccezioni

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

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, la funzione restituisce FALSE; in caso contrario, restituisce TRUE.

L'espressione di filtro nell'esempio utilizza la funzione GetExceptionCode 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.

Inoltre, l'uso dell'istruzione restituita nel blocco di __try di un gestore eccezioni differisce dall'uso di restituire nel blocco __try di un gestore di terminazione, che causa una terminazione anomala del blocco __try. Si tratta di un uso valido dell'istruzione return in un gestore di eccezioni.

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

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