Udostępnij za pośrednictwem


Występowanie wyjątków programowych

Niektóre z najczęstszych źródeł błędów programu nie są oflagowane jako wyjątki przez system. Na przykład, jeśli użytkownik spróbuje przydzielić blok pamięci, ale ilość pamięci jest niewystarczająca, czas wykonywania lub funkcja interfejsu API nie zgłosi wyjątku, ale zwróci kod błędu.

Można jednak traktować dowolny warunek jako wyjątek, wykrywając ten warunek w kodzie, a następnie zgłaszając go, wywołując funkcję RaiseException . Flagowanie błędów w ten sposób może przynieść korzyści obsługi wyjątków strukturalnych do wszelkiego rodzaju błędów w czasie wykonywania.

Aby użyć obsługi wyjątków strukturalnych z błędami:

  • Zdefiniuj własny kod wyjątku dla zdarzenia.

  • Wywołaj połączenie RaiseException po wykryciu problemu.

  • Użyj filtrów obsługi wyjątków, aby przetestować zdefiniowany kod wyjątku.

Plik <winerror.h> przedstawia format kodów wyjątków. Aby upewnić się, że nie zostanie zdefiniowany kod, który powoduje konflikt z istniejącym kodem wyjątku, należy ustawić trzeci najbardziej znaczący bit na 1. Cztery najbardziej znaczące bity powinny być ustawione, jak pokazano w poniższej tabeli.

Bity Zalecane ustawienie binarne opis
31-30 11 Te dwa bity opisują podstawowy stan kodu: 11 = błąd, 00 = sukces, 01 = informacyjny, 10 = ostrzeżenie.
29 1 Bit klienta. Wartość 1 dla kodów zdefiniowanych przez użytkownika.
28 0 Zarezerwowany bit. (Pozostawić ustawione na 0).

Można ustawić pierwsze dwa bity na ustawienie inne niż 11 binarnie, mimo że ustawienie „błąd” jest odpowiednie dla większości wyjątków. Należy pamiętać o ustawieniu bitów 29 i 28, jak pokazano w poprzedniej tabeli.

Wynikowy kod błędu powinien zatem mieć maksymalnie cztery bity ustawione na szesnastkowe E. Na przykład poniższe definicje definiują kody wyjątków, które nie powodują konfliktu z żadnymi kodami wyjątków systemu Windows. (Jednak trzeba sprawdzić kody, które są używane przez biblioteki DLL innych firm).

#define STATUS_INSUFFICIENT_MEM       0xE0000001
#define STATUS_FILE_BAD_FORMAT        0xE0000002

Po zdefiniowaniu kodu wyjątku można go użyć, aby zgłosić wyjątek. Na przykład następujący kod zgłasza STATUS_INSUFFICIENT_MEM wyjątek w odpowiedzi na problem z alokacją pamięci:

lpstr = _malloc( nBufferSize );
if (lpstr == NULL)
    RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);

Jeżeli wystarczy tylko zgłosić wyjątek, ostatnie trzy parametry można ustawić na 0. Trzy ostatnie parametry są przydatne do przekazywania informacji dodatkowych i ustawiania flagi, która uniemożliwia kontynuowanie wykonywania programów obsługi. Aby uzyskać więcej informacji, zobacz funkcję RaiseException w zestawie Windows SDK.

W filtrach obsługi wyjątków można przetestować zdefiniowane kody. Na przykład:

__try {
    ...
}
__except (GetExceptionCode() == STATUS_INSUFFICIENT_MEM ||
        GetExceptionCode() == STATUS_FILE_BAD_FORMAT )

Zobacz też

Pisanie procedury obsługi wyjątków
Obsługa wyjątków strukturalnych (C/C++)