Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
L'istruzione try-except
è un'estensione specifica di Microsoft che supporta la gestione strutturata delle eccezioni nei linguaggi C e C++.
// . . .
__try {
// guarded code
}
__except ( /* filter expression */ ) {
// termination code
}
// . . .
Grammatica
try-except-statement
:
__try
compound-statement
__except (
expression
)
compound-statement
Osservazioni:
L'istruzione try-except
è un'estensione Microsoft per i linguaggi C e C++. Consente alle applicazioni di destinazione di ottenere il controllo quando si verificano eventi che normalmente terminano l'esecuzione del programma. Tali eventi sono denominati eccezioni strutturate o eccezioni per brevità. Il meccanismo che gestisce queste eccezioni è denominato gestione delle eccezioni strutturata (SEH).
Per informazioni correlate, vedere l'istruzione try-finally.
Le eccezioni possono essere basate su hardware o basate su software. La gestione strutturata delle eccezioni è utile anche quando le applicazioni non possono eseguire completamente il ripristino da eccezioni hardware o software. SEH consente di visualizzare le informazioni sugli errori e di intercettare lo stato interno dell'applicazione per diagnosticare il problema. È particolarmente utile per problemi intermittenti che non sono facili da riprodurre.
Nota
La gestione eccezioni strutturata funziona con i file Win32 per i file di origine C++ e C. Tuttavia, non è progettato specificamente 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++, è consigliabile usare la gestione delle eccezioni C++ nativa: istruzioni try, catch e throw .
L'istruzione composta dopo la __try
clausola è il corpo o la sezione sorvegliata . L'espressione __except
è nota anche come espressione di filtro . Il valore determina la modalità di gestione dell'eccezione. L'istruzione composta dopo la clausola __except
è il gestore dell'eccezione. Il gestore specifica le azioni da eseguire se viene generata un'eccezione durante l'esecuzione della sezione del corpo. 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 sorvegliata o in qualsiasi routine chiamata alla sezione sorvegliata, l'espressione
__except
viene valutata. I tre valori possibili sono:EXCEPTION_CONTINUE_EXECUTION
(-1) Eccezione ignorata. Continuare l'esecuzione nel punto in cui si è verificata l'eccezione.EXCEPTION_CONTINUE_SEARCH
(0) Eccezione non riconosciuta. Continuare a cercare nello stack un gestore, prima di tutto per conteneretry-except
le istruzioni, quindi per i gestori con la precedenza più alta successiva.EXCEPTION_EXECUTE_HANDLER
(1) Viene riconosciuta l'eccezione. Trasferire il controllo al gestore eccezioni eseguendo l'istruzione composta, quindi continuare l'esecuzione__except
dopo il__except
blocco.
L'espressione __except
viene valutata come espressione C. È limitato a un singolo valore, all'operatore di espressione condizionale o all'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 valida per saltare da uno. Il gestore eccezioni non viene chiamato se un processo viene terminato al centro dell'esecuzione di un'istruzione try-except
.
Per la compatibilità con le versioni precedenti, _try, _except e _leave sono sinonimi per __try
, __except
e __leave
a meno che non sia specificata l'opzione del compilatore /Za (Disabilita estensioni del linguaggio).
Parola chiave __leave
La __leave
parola chiave è valida solo all'interno della sezione sorvegliata di un'istruzione try-except
e il relativo effetto consiste nel passare alla fine della sezione sorvegliata. L'esecuzione continua con la prima istruzione dopo il gestore dell'eccezione.
Un'istruzione goto
può anche uscire dalla sezione sorvegliata e non degrada le prestazioni come in un'istruzione try-finally . Questo perché la rimozione dello stack non si verifica. È tuttavia consigliabile usare la __leave
parola chiave anziché un'istruzione goto
. Il motivo è che è meno probabile che si commette un errore di programmazione se la sezione sorvegliata è grande o complessa.
Funzioni intrinseche di gestione delle eccezioni strutturate
La gestione strutturata delle eccezioni fornisce due funzioni intrinseche disponibili per l'uso con l'istruzione try-except
GetExceptionCode e GetExceptionInformation.
GetExceptionCode
restituisce il codice (intero a 32 bit) dell'eccezione.
La funzione GetExceptionInformation
intrinseca restituisce un puntatore a una struttura EXCEPTION_POINTERS contenente informazioni aggiuntive sull'eccezione. Tramite questo puntatore, è possibile accedere allo stato del computer esistente al momento di un'eccezione hardware. La struttura è analoga alla seguente:
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
I tipi di PEXCEPTION_RECORD
puntatore e PCONTEXT
sono definiti nel file <di inclusione winnt.h> e _CONTEXT
_EXCEPTION_RECORD
sono definiti nel file <di inclusione excpt.h>
È possibile usare GetExceptionCode
all'interno del gestore eccezioni. Tuttavia, è possibile usare GetExceptionInformation
solo all'interno dell'espressione di filtro delle eccezioni. Le informazioni a cui punta si trova in genere nello stack e non sono più disponibili quando il controllo viene trasferito al gestore eccezioni.
La funzione intrinseca AbnormalTermination è disponibile all'interno di 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 oggetti intrinseci:
GetExceptionCode
equivale a _exception_code
GetExceptionInformation
equivale a _exception_info
AbnormalTermination
equivale 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
Vedi anche
Scrittura di un gestore eccezioni
Structured Exception Handling (C/C++)
Parole chiave