Istruzione try-except
Sezione specifica Microsoft
Di seguito è riportata la sintassi dell'istruzione try-except:
__try
{
// guarded code
}
__except ( expression )
{
// exception handler code
}
Note
L'istruzione try-except è un'estensione Microsoft dei linguaggi C e C++ che consentono alle applicazioni di destinazione di ottenere il controllo quando si verificano gli eventi che generalmente terminano l'esecuzione del programma. Tali eventi vengono chiamati eccezioni e il meccanismo che tratta le eccezioni viene chiamato gestione delle eccezioni strutturate.
Per informazioni correlate, vedere l'istruzione try-finally.
Le eccezioni possono essere basate sull'hardware o basate sul software. Anche quando le applicazioni non possono completamente recuperare le eccezioni hardware o software, la gestione delle eccezioni strutturata consente di visualizzare informazioni sugli errori e intercettare lo stato interno dell'applicazione per diagnosticare il problema. Ciò è particolarmente utile per i problemi saltuari che non possono essere riprodotti facilmente.
Nota
La gestione eccezioni strutturata funziona con i file Win32 per i file di origine C++ e C.Tuttavia, non è progettato in particolare per C++.È possibile garantire maggiore portabilità del codice tramite la gestione delle eccezioni C++.Inoltre, la gestione eccezioni C++ è più flessibile, in quanto può gestire le eccezioni di qualsiasi tipo.Per i programmi C++, si consiglia di utilizzare il meccanismo di gestione delle eccezioni C++ (istruzioni try, catch e throw).
L'istruzione composta dopo la clausola __try è il corpo o la sezione protetta. L'istruzione composta dopo la clausola __except è il gestore dell'eccezione. Il gestore specifica un set di azioni da intraprendere se viene generata un'eccezione durante l'esecuzione del corpo della sezione protetta. L'esecuzione procede nel modo seguente:
La sezione protetta viene eseguita.
Se non si verifica alcuna eccezione durante l'esecuzione della sezione protetta, l'esecuzione continuerà nell'istruzione dopo la clausola __except.
Se si verifica un'eccezione durante l'esecuzione della sezione protetta o nelle routine chiamata dalla sezione protetta, __except expression(chiamata espressione filter) viene valutata e il valore determina come viene gestita l'eccezione. Vi sono tre valori:
EXCEPTION_CONTINUE_EXECUTION (–1) L'eccezione viene chiusa. Continuare l'esecuzione nel punto in cui si è verificata l'eccezione.
EXCEPTION_CONTINUE_SEARCH (0) L'eccezione non viene riconosciuta. Continuare la ricerca dello stack per un gestore, anzitutto per contenere le istruzioni try-except, quindi per i gestori con la precedenza successiva più elevata.
EXCEPTION_EXECUTE_HANDLER (1) L'eccezione è riconosciuta. Trasferire il controllo al gestore eccezioni eseguendo l'istruzione composta __except, quindi continuare l'esecuzione dopo il blocco __except.
Poiché l'espressione __except viene valutata come un'espressione di tipo C, è limitata a un singolo valore, l'operatore di espressione condizionale o l'operatore virgola. Se è necessaria un'elaborazione più estesa, l'espressione può chiamare una routine che restituisce uno dei tre valori sopra elencati.
Ogni applicazione può essere associata al proprio gestore di eccezioni.
Non è valido passare a un'istruzione __try, ma è valido uscire da una. Il gestore dell'eccezione non viene chiamato se un processo viene terminato nel corso dell'esecuzione di un'istruzione try-except.
Per ulteriori informazioni, vedere l'articolo della Knowledge Base Q315937: Procedura: Intercettare l'overflow dello stack nell'applicazione Visual C++.
La parola chiave __leave
La parola chiave __leave è valida solo nella sezione protetta di un'istruzione try-except e consente di passare alla fine della sezione protetta. L'esecuzione continua con la prima istruzione dopo il gestore dell'eccezione.
Un'istruzione goto può inoltre uscire dalla sezione protetta e ciò non comporta una riduzione delle prestazioni come in un'istruzione try-finally poiché non si verifica la rimozione dello stack. Tuttavia, è consigliabile utilizzare la parola chiave __leave anziché un'istruzione goto perché è meno probabile eseguire un errore di programmazione se la sezione protetta è grande o complessa.
Funzioni intrinseche di gestione eccezioni strutturata
La gestione eccezioni strutturata fornisce inoltre due funzioni intrinseche disponibili per l'utilizzo con l'istruzione try-except: GetExceptionCode e GetExceptionInformation.
GetExceptionCode restituisce il codice (un numero intero a 32 bit) dell'eccezione.
La funzione intrinseca GetExceptionInformation restituisce un puntatore a una struttura che contiene altre informazioni sull'eccezione. Tramite questo puntatore, è possibile accedere allo stato del computer esistente al momento di un'eccezione hardware. La struttura è la seguente:
struct _EXCEPTION_POINTERS {
EXCEPTION_RECORD *ExceptionRecord,
CONTEXT *ContextRecord }
I tipi di puntatore _EXCEPTION_RECORD e _CONTEXT sono definiti nel file di inclusione EXCPT.H.
È possibile utilizzare GetExceptionCode all'interno del gestore di eccezioni. Tuttavia, è possibile utilizzare GetExceptionInformation solo all'interno dell'espressione di filtro eccezioni. Le informazioni che indica in genere sono nello stack e non sono più disponibili quando il controllo viene trasferito al gestore di eccezioni.
La funzione intrinseca AbnormalTermination è disponibile in un gestore di terminazione. Restituisce 0 se il corpo dell'istruzione try-finally termina in sequenza. In tutti gli altri casi, restituisce 1.
EXCPT.H definisce alcuni nomi alternativi per questi intrinseci:
GetExceptionCode è equivalente a _exception_code
GetExceptionInformation è equivalente a _exception_info
AbnormalTermination è equivalente a _abnormal_termination
Esempio
// exceptions_try_except_Statement.cpp
// Example of try-except and try-finally statements
#include <stdio.h>
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
puts("in filter.");
if (code == EXCEPTION_ACCESS_VIOLATION) {
puts("caught AV as expected.");
return EXCEPTION_EXECUTE_HANDLER;
}
else {
puts("didn't catch AV, unexpected.");
return EXCEPTION_CONTINUE_SEARCH;
};
}
int main()
{
int* p = 0x00000000; // pointer to NULL
puts("hello");
__try{
puts("in try");
__try{
puts("in try");
*p = 13; // causes an access violation exception;
}__finally{
puts("in finally. termination: ");
puts(AbnormalTermination() ? "\tabnormal" : "\tnormal");
}
}__except(filter(GetExceptionCode(), GetExceptionInformation())){
puts("in except");
}
puts("world");
}
Output
hello
in try
in try
in filter.
caught AV as expected.
in finally. termination:
abnormal
in except
world
Fine sezione specifica Microsoft
Vedere anche
Riferimenti
Scrittura di un gestore di eccezioni