Structured Exception Handling (C/C++)
La gestione strutturata delle eccezioni (SEH) è un'estensione Microsoft per C e C++ per gestire determinate situazioni di codice eccezionali, ad esempio errori hardware, normalmente. Anche se Windows e Microsoft C++ supportano SEH, è consigliabile usare la gestione delle eccezioni C++ standard ISO nel codice C++. Rende il codice più portatile e flessibile. Tuttavia, per mantenere il codice esistente o per determinati tipi di programmi, potrebbe comunque essere necessario usare SEH.
Specifico di Microsoft:
Grammatica
try-except-statement
:
__try
compound-statement
__except
(
filter-expression
)
compound-statement
try-finally-statement
:
__try
compound-statement
__finally
compound-statement
Osservazioni:
Con SEH, è possibile assicurarsi che le risorse, ad esempio blocchi di memoria e file, vengano rilasciati correttamente se l'esecuzione termina in modo imprevisto. È anche possibile gestire problemi specifici, ad esempio memoria insufficiente, usando codice strutturato conciso che non si basa su goto
istruzioni o test elaborati dei codici restituiti.
Le try-except
istruzioni e try-finally
indicate in questo articolo sono estensioni Microsoft per i linguaggi C e C++. Supportano la gestione delle eccezioni strutturata permettendo alle applicazioni di ottenere il controllo di un programma dopo eventi che altrimenti terminerebbero l'esecuzione. Anche se la gestione delle eccezioni strutturata può essere usata con file di origine C++, non è stata progettata in modo specifico per C++. Se si usa SEH in un programma C++ compilato usando l'opzione /EHa
o /EHsc
, vengono chiamati distruttori per gli oggetti locali, ma altri comportamenti di esecuzione potrebbero non essere quello previsto. Per un'illustrazione, vedere l'esempio più avanti in questo articolo. Nella maggior parte dei casi, invece di SEH, è consigliabile usare la gestione delle eccezioni C++ standard ISO. L'uso della gestione delle eccezioni C++ permette di assicurare una maggiore portabilità del codice e la gestione di qualsiasi tipo di eccezione.
Se si dispone di codice C che usa SEH, è possibile combinarlo con il codice C++ che usa la gestione delle eccezioni C++. Per informazioni, vedere Gestire eccezioni strutturate in C++.
Sono disponibili due meccanismi per la gestione delle eccezioni strutturata:
Gestori eccezioni, o
__except
blocchi, che possono rispondere o ignorare l'eccezione in base alfilter-expression
valore . Per altre informazioni, vederetry-except
l'istruzione .Gestori di terminazione, o
__finally
blocchi, che vengono sempre chiamati, indipendentemente dal fatto che un'eccezione causi o meno la terminazione. Per altre informazioni, vederetry-finally
l'istruzione .
Questi due tipi di gestori sono distinti, ma sono strettamente correlati tramite un processo noto come rimozione dello stack. Quando si verifica un'eccezione strutturata, Windows cerca il gestore eccezioni installato più di recente attualmente attivo. Il gestore può procedere nei tre modi seguenti:
Non è possibile riconoscere l'eccezione e passare il controllo ad altri gestori (
EXCEPTION_CONTINUE_SEARCH
).Riconoscere l'eccezione ma ignorarla (
EXCEPTION_CONTINUE_EXECUTION
).Riconoscere l'eccezione e gestirla (
EXCEPTION_EXECUTE_HANDLER
).
È possibile che il gestore di eccezioni che riconosce l'eccezione non si trovi nella funzione che era in esecuzione quando si è verificata l'eccezione. Può trovarsi in una funzione molto più alta nello stack. La funzione attualmente in esecuzione e tutte le altre funzioni nel frame dello stack vengono terminate. Durante questo processo, lo stack viene scollegato. Ovvero, le variabili locali non statiche delle funzioni terminate vengono cancellate dallo stack.
Durante la rimozione dello stack, il sistema operativo chiama eventuali gestori di terminazione scritti per ogni funzione. Usando un gestore di terminazione, si puliscono le risorse che altrimenti rimarranno aperte a causa di una terminazione anomala. Se è stata immessa una sezione critica, è possibile chiuderla nel gestore di terminazione. Quando il programma verrà arrestato, è possibile eseguire altre attività di manutenzione, ad esempio la chiusura e la rimozione di file temporanei.
Passaggi successivi
Esempio
Come indicato in precedenza, i distruttori per gli oggetti locali vengono chiamati se si usa SEH in un programma C++ e compilarlo usando l'opzione /EHa
o /EHsc
. Tuttavia, il comportamento durante l'esecuzione potrebbe non essere quello previsto se si usano anche eccezioni C++. Questo esempio illustra queste differenze comportamentali.
#include <stdio.h>
#include <Windows.h>
#include <exception>
class TestClass
{
public:
~TestClass()
{
printf("Destroying TestClass!\n");
}
};
__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
printf("Throwing C++ exception\n");
throw std::exception("");
#else
printf("Triggering SEH exception\n");
volatile int *pInt = 0x00000000;
*pInt = 20;
#endif
}
__declspec(noinline) void TestExceptions()
{
TestClass d;
TestCPPEX();
}
int main()
{
__try
{
TestExceptions();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("Executing SEH __except block\n");
}
return 0;
}
Se si usa /EHsc
per compilare questo codice ma la macro CPPEX
del controllo di test locale non è definita, il TestClass
distruttore non viene eseguito. L'output sarà simile al seguente:
Triggering SEH exception
Executing SEH __except block
Se si usa /EHsc
per compilare il codice e CPPEX
viene definito usando /DCPPEX
(in modo che venga generata un'eccezione C++), il TestClass
distruttore viene eseguito e l'output è simile al seguente:
Throwing C++ exception
Destroying TestClass!
Executing SEH __except block
Se si usa /EHa
per compilare il codice, il TestClass
distruttore esegue se è stata generata un'eccezione usando un'espressione C++ throw
standard o se si usa SEH. Ovvero, se CPPEX
è definito o meno. L'output sarà simile al seguente:
Throwing C++ exception
Destroying TestClass!
Executing SEH __except block
Per altre informazioni, vedere /EH
(Modello di gestione delle eccezioni).
END Specifico di Microsoft
Vedi anche
Gestione delle eccezioni
Parole chiave
<exception>
Errori e gestione delle eccezioni
Gestione strutturata delle eccezioni (Windows)