Udostępnij za pośrednictwem


try-except — instrukcja

Specyficzne dla firmy Microsoft

Następująca składnia opisuje wyrażenie try-except:

__try 
{
   // guarded code
}
__except ( expression )
{
   // exception handler code
}

Uwagi

Wyrażenie try-except to rozszerzenie firmy Microsoft do języków C i C++, które umożliwiają aplikacji docelowej na uzyskanie kontroli nad zdarzeniami, które normalnie powodują zamknięcie programu.Takie zdarzenia nazywane są wyjątkami, a mechanizm, który zajmuje się wyjątkami nazywa się strukturalną obsługą wyjątków.

Aby uzyskać pokrewne informacje, zobacz instrukcja try-finally.

Wyjątki mogą być sprzętowe lub programowe.Nawet wtedy, gdy aplikacje nie może całkowicie odzyskać sprawności po wystąpieniu wyjątku sprzętowego lub programowego, strukturalna obsługa wyjątków umożliwia wyświetlenie informacji o błędzie i przechwycić wewnętrzny stan aplikacji, aby pomóc w zdiagnozowaniu problemu.Jest to szczególnie użyteczne w przypadku sporadycznych problemów, których nie można łatwo odtworzyć.

[!UWAGA]

Strukturalna obsługa wyjątków działa z Win32 dla plików z kodem źródłowym Ci C++.Jednakże nie jest szczególnie przeznaczona dla języka C++.Można zapewnić, że kod będzie bardziej przenośny przy użyciu obsługi wyjątków C++.Ponadto obsługa wyjątków C++ jest bardziej elastyczna, pod tym względem, że może obsługiwać wyjątki dowolnego typu.Dla programów C++, zalecane jest używanie mechanizmu obsługi wyjątków C++ (instrukcje try, catch i throw).

Złożone wyrażenie po klauzuli __try jest ciałem chronionej sekcji.Złożone wyrażenie po klauzuli __except to obsługa wyjątków.Kod obsługi wyjątku określa zestaw akcji, które zostaną wykonane jeśli wystąpi wyjątek w ciele chronionej sekcji.Wykonanie działa w następujący sposób:

  1. Sekcja chroniona jest wykonywana.

  2. Jeśli podczas wykonywania sekcji strzeżonej nie wystąpi wyjątek program kontynuuje wykonywanie instrukcji znajdującej się po klauzuli __except.

  3. Jeśli wystąpi wyjątek podczas wykonywania sekcji chronionej lub wyjątek wystąpi w dowolnym fragmencie wywoływanym przez sekcję chronioną, wyrażenie__except (nazywane wyrażeniem filter) jest sprawdzane a wartość określa sposób obsługi wyjątku.Istnieją trzy wartości:

    EXCEPTION_CONTINUE_EXECUTION (-1) Wyjątek zostaje odrzucony.Kontynuuj wykonywanie w punkcie, w którym wystąpił wyjątek.

    EXCEPTION_CONTINUE_SEARCH (0)   Wyjątek nie został rozpoznany.Kontynuuj przeszukiwanie stosu w celu znalezienia fragmentu obsługującego wyjątek, najpierw zawierającego wyrażenia try-except a następnie z następnym największym priorytetem.

    EXCEPTION_EXECUTE_HANDLER (1)   Wyjątek został rozpoznany.Przenieść kontrolę do obsługi wyjątków przez wykonywanie złożonego wyrażenia __except, a następnie kontynuuj wykonywanie po bloku __except.

Ponieważ wyrażenie __except jest oceniane jak wyrażenie C, to jest ograniczone do pojedynczej wartości, operatora wyrażenia warunkowego lub operatora przecinka.Jeśli wymagane jest bardziej rozległe przetwarzanie, wyrażenie może wywołać procedurę, która zwraca jedną z trzech wartości wymienionych powyżej.

Każda aplikacja może mieć własną obsługę wyjątków.

Niedozwolonym jest przejście do instrukcji __try, ale dozwolonym jest wyjście z niej.Obsługa wyjątków nie jest wywoływana, jeśli proces zostanie zakończony w środku wykonywania wyrażenia try-except.

Aby uzyskać więcej informacji, zobacz artykuł Bazy wiedzy Knowledge Base Q315937: HOW TO: Trap Stack Overflow in a Visual C++ Application.

Słowo kluczowe __leave

Słowo kluczowe __leave jest prawidłowe tylko wewnątrz sekcji chronionej wyrażenia try-except a jego efektem jest przeskoczenie do końca sekcji strzeżonej.Wykonywanie jest kontynuowane po pierwszej instrukcji następującej po obsłudze wyjątków.

Instrukcja goto może również przeskoczyć poza sekcję strzeżoną i to nie zmniejsza wydajności, tak jak w wyrażeniu try-finally ponieważ nie występuję odwrócenie stosu.Jednakże, firma Microsoft zaleca użycie słowa kluczowego __leave niż instrukcji goto ponieważ zmniejsza to prawdopodobieństwo popełnienia błędu w dużej lub złożonej sekcji chronionej.

Wewnętrzne funkcje strukturalnej obsługi wyjątków

Strukturalna obsługa wyjątków zapewnia dwie funkcje wewnętrzne, które są dostępne do użycia w wyrażeniu try-except: GetExceptionCode i GetExceptionInformation.

GetExceptionCode zwraca kod wyjątku (liczba całkowita 32-bitowa).

Wewnętrzna funkcja GetExceptionInformation zwraca wskaźnik do struktury zawierającej dodatkowe informacje o wyjątku.Za pomocą tego wskaźnika można uzyskać dostęp do stanu maszyny w momencie wystąpienia wyjątku sprzętowego.Struktura jest następująca:

struct _EXCEPTION_POINTERS {
      EXCEPTION_RECORD *ExceptionRecord,
      CONTEXT *ContextRecord }

Typy wskaźnika _EXCEPTION_RECORD i _CONTEXT są zdefiniowane w dołączanym pliku EXCPT.H.

GetExceptionCode można użyć w ramach obsługi wyjątków.Jednakże, GetExceptionInformation można użyć tylko w wyrażeniu filtru wyjątków.Informacje na które wskazuje są na ogół na stosie i nie będą dłużej dostępne po przekazaniu kontroli do obsługi wyjątków.

Wewnętrzna funkcja AbnormalTermination jest dostępna w ramach obsługi zakończenia programu.Zwraca 0 jeśli ciało wyrażenia try-finally kończy się sekwencyjnie.We wszystkich pozostałych przypadkach zwraca wartość 1.

EXCPT.H definiuje kilka nazw alternatywnych dla funkcji wewnętrznych:

GetExceptionCode jest równoważne z _exception_code

GetExceptionInformation jest równoważne z _exception_info

AbnormalTermination jest równoważne z _abnormal_termination

Przykład

// 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");

}

Dane wyjściowe

hello
in try
in try
in filter.
caught AV as expected.
in finally. termination:
        abnormal
in except
world

KONIEC informacji specyficznych dla firmy Microsoft

Zobacz też

Informacje

Pisanie programu do obsługi wyjątku

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

Słowa kluczowe języka C++