Obsługa wyjątków strukturalnych (C/C++)Structured Exception Handling (C/C++)

Obsługa wyjątków strukturalnych (SEH) to rozszerzenie firmy Microsoft do języka C, które obsługuje pewne wyjątkowe sytuacje związane z kodem, takie jak błędy sprzętu.Structured exception handling (SEH) is a Microsoft extension to C to handle certain exceptional code situations, such as hardware faults, gracefully. Chociaż systemy Windows i Microsoft C++ obsługują SEH, zalecamy użycie obsługi wyjątków ISO-standard C++.Although Windows and Microsoft C++ support SEH, we recommend that you use ISO-standard C++ exception handling. Sprawia, że kod jest bardziej przenośny i elastyczny.It makes your code more portable and flexible. Jednak aby zachować istniejący kod lub dla określonych rodzajów programów, nadal może być konieczne użycie SEH.However, to maintain existing code or for particular kinds of programs, you still might have to use SEH.

Specyficzne dla firmy Microsoft:Microsoft-specific:

GramatykaGrammar

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

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

UwagiRemarks

Za pomocą SEH można upewnić się, że zasoby, takie jak bloki pamięci i pliki, zostaną wydane prawidłowo, jeśli wykonanie nieoczekiwanie zakończy się.With SEH, you can ensure that resources, such as memory blocks and files, get released correctly if execution unexpectedly terminates. Można także obsłużyć konkretne problemy — na przykład niewystarczająca ilość pamięci — przy użyciu zwięzłego kodu strukturalnego, który nie polega na goto instrukcjach lub opracowywaniu testów kodów powrotu.You can also handle specific problems—for example, insufficient memory—by using concise structured code that doesn't rely on goto statements or elaborate testing of return codes.

try-exceptInstrukcje i, try-finally do których odwołuje się w tym artykule, są rozszerzeniami firmy Microsoft do języka C.The try-except and try-finally statements referred to in this article are Microsoft extensions to the C language. Obsługują one SEH, umożliwiając aplikacjom uzyskanie kontroli nad programem po zdarzeniach, które w przeciwnym razie spowodują zakończenie wykonywania.They support SEH by enabling applications to gain control of a program after events that would otherwise terminate execution. Chociaż SEH współpracuje z plikami źródłowymi języka C++, nie jest to zaprojektowane specjalnie dla języka C++.Although SEH works with C++ source files, it's not specifically designed for C++. Jeśli używasz SEH w programie C++ kompilowanym przy użyciu opcji /EHa lub /EHsc , destruktory dla obiektów lokalnych są wywoływane, ale inne zachowanie wykonywania może nie być oczekiwane.If you use SEH in a C++ program that you compile by using the /EHa or /EHsc option, destructors for local objects are called but other execution behavior might not be what you expect. Aby zapoznać się z ilustracją, zobacz przykład w dalszej części tego artykułu.For an illustration, see the example later in this article. W większości przypadków zamiast SEH zaleca się użycie obsługi wyjątkówISO-standard c++, która obsługuje również kompilator języka Microsoft c++.In most cases, instead of SEH we recommend that you use ISO-standard C++ exception handling, which the Microsoft C++ compiler also supports. Korzystając z obsługi wyjątków C++, można upewnić się, że kod jest bardziej przenośny i można obsługiwać wyjątki dowolnego typu.By using C++ exception handling, you can ensure that your code is more portable, and you can handle exceptions of any type.

Jeśli masz kod C, który używa SEH, możesz go mieszać z kodem C++, który korzysta z obsługi wyjątków C++.If you have C code that uses SEH, you can mix it with C++ code that uses C++ exception handling. Aby uzyskać więcej informacji, zobacz Obsługa wyjątków strukturalnych w języku C++.For information, see Handle structured exceptions in C++.

Istnieją dwa mechanizmy SEH:There are two SEH mechanisms:

Te dwa rodzaje obsługi są różne, ale są ściśle powiązane z procesem znanym jako odwracanie stosu.These two kinds of handlers are distinct, but are closely related through a process known as unwinding the stack. Gdy wystąpi wyjątek strukturalny, system Windows szuka ostatnio zainstalowanego programu obsługi wyjątków, który jest obecnie aktywny.When a structured exception occurs, Windows looks for the most recently installed exception handler that's currently active. Program obsługi może wykonać jedną z trzech czynności:The handler can do one of three things:

  • Nie można rozpoznać wyjątku i przekazać kontroli do innych programów obsługi.Fail to recognize the exception and pass control to other handlers.

  • Rozpoznaj wyjątek, ale Odrzuć go.Recognize the exception but dismiss it.

  • Rozpoznać wyjątek i obsłużyć go.Recognize the exception and handle it.

Program obsługi wyjątków, który rozpoznaje wyjątek, może nie znajdować się w funkcji, która była uruchomiona, gdy wystąpił wyjątek.The exception handler that recognizes the exception may not be in the function that was running when the exception occurred. Może ona znajdować się w funkcji znacznie większej na stosie.It may be in a function much higher on the stack. Aktualnie uruchomiona funkcja i wszystkie inne funkcje w ramce stosu są kończone.The currently running function and all other functions on the stack frame are terminated. W trakcie tego procesu stos jestrozłożony.During this process, the stack is unwound. Oznacza to, że lokalne zmienne niestatyczne dla zakończonych funkcji są wyczyszczone ze stosu.That is, local non-static variables of terminated functions get cleared from the stack.

Po odłączeniu stosu system operacyjny wywołuje wszystkie programy obsługi zakończenia, które zostały zapisaną dla każdej funkcji.As it unwinds the stack, the operating system calls any termination handlers that you've written for each function. Za pomocą procedury obsługi zakończenia, można wyczyścić zasoby, które w przeciwnym razie pozostaną otwarte z powodu nietypowego zakończenia.By using a termination handler, you clean up resources that otherwise would remain open because of an abnormal termination. Jeśli wprowadzono sekcję krytyczną, możesz ją zamknąć w programie obsługi zakończenia.If you've entered a critical section, you can exit it in the termination handler. Gdy program zostanie zamknięty, można wykonywać inne zadania dla gospodarstw domowych, takie jak zamykanie i usuwanie plików tymczasowych.When the program is going to shut down, you can do other housekeeping tasks such as closing and removing temporary files.

Następne krokiNext steps

PrzykładExample

Jak wspomniano wcześniej, destruktory dla obiektów lokalnych są wywoływane, jeśli używasz SEH w programie C++ i kompilujesz go przy użyciu /EHa /EHsc opcji lub.As stated earlier, destructors for local objects are called if you use SEH in a C++ program and compile it by using the /EHa or /EHsc option. Zachowanie podczas wykonywania może jednak nie być oczekiwane w przypadku korzystania z wyjątków C++.However, the behavior during execution may not be what you expect if you're also using C++ exceptions. Ten przykład ilustruje te różnice w zachowaniu.This example demonstrates these behavioral differences.

#include <stdio.h>
#include <Windows.h>
#include <exception>

class TestClass
{
public:
    ~TestClass()
    {
        printf("Destroying TestClass!\r\n");
    }
};

__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
    printf("Throwing C++ exception\r\n");
    throw std::exception("");
#else
    printf("Triggering SEH exception\r\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\r\n");
    }

    return 0;
}

Jeśli używasz /EHsc do kompilowania tego kodu, ale makro kontroli testu lokalnego CPPEX jest niezdefiniowane, TestClass destruktor nie zostanie uruchomiony.If you use /EHsc to compile this code but the local test control macro CPPEX is undefined, the TestClass destructor doesn't run. Dane wyjściowe wyglądają następująco:The output looks like this:

Triggering SEH exception
Executing SEH __except block

Jeśli używasz /EHsc do kompilowania kodu i CPPEX jest on definiowany przy użyciu /DCPPEX (w celu wygenerowania wyjątku C++), destruktor zostanie TestClass uruchomiony, a dane wyjściowe wyglądają następująco:If you use /EHsc to compile the code and CPPEX is defined by using /DCPPEX (so that a C++ exception is thrown), the TestClass destructor runs, and the output looks like this:

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

Jeśli używasz /EHa do kompilowania kodu, TestClass destruktor wykonuje, czy wyjątek został zgłoszony przez użycie std::throw lub przy użyciu SEH, aby wyzwolić wyjątek.If you use /EHa to compile the code, the TestClass destructor executes whether the exception was thrown by using std::throw or by using SEH to trigger the exception. Oznacza to, czy CPPEX jest zdefiniowany, czy nie.That is, whether CPPEX is defined or not. Dane wyjściowe wyglądają następująco:The output looks like this:

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

Aby uzyskać więcej informacji, zobacz /EH (model obsługi wyjątków).For more information, see /EH (Exception Handling Model).

ZAKOŃCZENIE specyficzne dla firmy MicrosoftEND Microsoft-specific

Zobacz teżSee also

Obsługa wyjątkówException handling
Słowa kluczoweKeywords
<exception>
Błędy i obsługa wyjątkówErrors and exception handling
Strukturalna obsługa wyjątków (system Windows)Structured Exception Handling (Windows)