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:
Sekcja chroniona jest wykonywana.
Jeśli podczas wykonywania sekcji strzeżonej nie wystąpi wyjątek program kontynuuje wykonywanie instrukcji znajdującej się po klauzuli __except.
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