Delen via


Verwerking van gestructureerde uitzonderingen (C/C++)

Structured Exception Handling (SEH) is een Microsoft-extensie voor C en C++ voor het afhandelen van bepaalde uitzonderlijke codesituaties, zoals hardwarefouten, zonder problemen. Hoewel Windows en Microsoft C++ SEH ondersteunen, wordt u aangeraden iso-standaard C++ uitzonderingsafhandeling te gebruiken in C++-code. Het maakt uw code draagbaarder en flexibeler. Als u echter bestaande code of voor bepaalde soorten programma's wilt onderhouden, moet u mogelijk nog steeds SEH gebruiken.

Microsoft-specifiek:

Grammatica

try-except-statement :
__try compound-statement __except ( filter-expression ) compound-statement

try-finally-statement :
__try compound-statement __finally compound-statement

Opmerkingen

Met SEH kunt u ervoor zorgen dat resources, zoals geheugenblokken en bestanden, correct worden vrijgegeven als de uitvoering onverwacht wordt beëindigd. U kunt ook specifieke problemen afhandelen, bijvoorbeeld onvoldoende geheugen, door beknopte gestructureerde code te gebruiken die niet afhankelijk is goto van instructies of uitgebreide tests van retourcodes.

De try-except instructies try-finally waarnaar in dit artikel wordt verwezen, zijn Microsoft-extensies voor de C- en C++-talen. Ze ondersteunen SEH door toepassingen in staat te stellen controle te krijgen over een programma na gebeurtenissen die anders de uitvoering zouden beëindigen. Hoewel SEH werkt met C++ bronbestanden, is het niet specifiek ontworpen voor C++. Als u SEH gebruikt in een C++-programma dat u compileert met behulp van de /EHa of /EHsc optie, worden destructors voor lokale objecten aangeroepen, maar ander uitvoeringsgedrag is mogelijk niet wat u verwacht. Zie het voorbeeld verderop in dit artikel voor een afbeelding. In de meeste gevallen wordt u aangeraden in plaats van SEH iso-standaard C++ uitzonderingsafhandeling te gebruiken. Door de verwerking van C++-uitzonderingen te gebruiken, kunt u ervoor zorgen dat uw code draagbaarder is en u kunt uitzonderingen van elk type afhandelen.

Als u C-code hebt die gebruikmaakt van SEH, kunt u deze combineren met C++-code die gebruikmaakt van de verwerking van C++-uitzonderingen. Zie Gestructureerde uitzonderingen verwerken in C++voor meer informatie.

Er zijn twee SEH-mechanismen:

  • Uitzonderingshandlers of __except blokken, die op de uitzondering kunnen reageren of sluiten op basis van de filter-expression waarde. Zie de instructie voor meer informatietry-except.

  • Beëindigingshandlers of __finally blokken, die altijd worden aangeroepen, ongeacht of een uitzondering beëindiging veroorzaakt of niet. Zie de instructie voor meer informatietry-finally.

Deze twee soorten handlers zijn verschillend, maar zijn nauw verwant door een proces dat bekend staat als het afwikkelen van de stapel. Wanneer er een gestructureerde uitzondering optreedt, zoekt Windows naar de laatst geïnstalleerde uitzonderingshandler die momenteel actief is. De handler kan een van de volgende drie dingen doen:

  • Kan de uitzondering niet herkennen en het besturingselement doorgeven aan andere handlers (EXCEPTION_CONTINUE_SEARCH).

  • De uitzondering herkennen, maar deze negeren (EXCEPTION_CONTINUE_EXECUTION).

  • De uitzondering herkennen en afhandelen (EXCEPTION_EXECUTE_HANDLER).

De uitzonderingshandler die de uitzondering herkent, bevindt zich mogelijk niet in de functie die werd uitgevoerd toen de uitzondering plaatsvond. Het kan veel hoger zijn in een functie op de stapel. De momenteel actieve functie en alle andere functies in het stackframe worden beëindigd. Tijdens dit proces is de stack onwikkeld. Dat wil zeggen dat lokale niet-statische variabelen van beëindigde functies worden gewist uit de stack.

Wanneer de stack wordt afgewikkeld, roept het besturingssysteem alle beëindigingshandlers aan die u voor elke functie hebt geschreven. Door een beëindigingshandler te gebruiken, schoont u resources op die anders open zouden blijven vanwege een abnormale beëindiging. Als u een kritieke sectie hebt ingevoerd, kunt u deze afsluiten in de beëindigingshandler. Wanneer het programma wordt afgesloten, kunt u andere huishoudtaken uitvoeren, zoals het sluiten en verwijderen van tijdelijke bestanden.

Volgende stappen

Voorbeeld

Zoals eerder vermeld, worden destructors voor lokale objecten aangeroepen als u SEH in een C++-programma gebruikt en compileert met behulp van de /EHa of /EHsc optie. Het gedrag tijdens de uitvoering is echter mogelijk niet wat u verwacht als u ook C++ uitzonderingen gebruikt. In dit voorbeeld ziet u deze gedragsverschillen.

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

Als u /EHsc deze code compileert, maar de lokale controlemacro CPPEX niet is gedefinieerd, wordt de TestClass destructor niet uitgevoerd. De uitvoer ziet er als volgt uit:

Triggering SEH exception
Executing SEH __except block

Als u /EHsc de code compileert en CPPEX wordt gedefinieerd met behulp van /DCPPEX (zodat er een C++-uitzondering wordt gegenereerd), wordt de TestClass destructor uitgevoerd en ziet de uitvoer er als volgt uit:

Throwing C++ exception
Destroying TestClass!
Executing SEH __except block

Als u /EHa de code compileert, wordt met de TestClass destructor uitgevoerd of er een uitzondering is opgetreden met behulp van een standaard C++ throw -expressie of met behulp van SEH. Dat wil gezegd, of CPPEX het nu wel of niet is gedefinieerd. De uitvoer ziet er als volgt uit:

Throwing C++ exception
Destroying TestClass!
Executing SEH __except block

Zie (Uitzonderingsafhandelingsmodel) voor/EH meer informatie.

Microsoft-specifiek beëindigen

Zie ook

afhandeling van uitzonderingen
Zoekwoorden
<exception>
Afhandeling van fouten en uitzonderingen
Verwerking van gestructureerde uitzonderingen (Windows)