2010-09-16 22 views

Odpowiedz

12

Powinieneś użyć bloku try/catch.

Tak jak inni już odpowiedzieli, __try/__except służy do przechwytywania SEH (błędy generowane przez okno), a nie do przechwytywania ogólnych wyjątków.

Co najważniejsze, __try i __catch nie mogą uruchamiać destruktorów języka C++ ani poprawnie rozwijać stosu podczas zgłaszania wyjątku.

Z wyjątkiem rzadkich przypadków, nigdy nie należy próbować łapać wyjątków SEH.

EDIT: Cóż, była pozytywna na to (to co ja zawsze mówiono), ale mówi, że widocznie @Hans jest przełącznik kompilator można użyć, aby to zmienić. Myślę, że dokumenty na temat /EHa są mylące, a przynajmniej niekompletne, na temat tego, co się tutaj dzieje. Jeśli ktoś znajdzie ostateczne dokumenty, które okażą się błędne, z przyjemnością usunę tę odpowiedź.

Nawet jeśli okaże się, to jest fałszywy, należy nadal używać try i catch po prostu dlatego, że są standardowe, natomiast __try i __except nie są.

+0

Więc nie rozwija się stos? Oznacza to, że prawdopodobnie złym pomysłem jest użycie '__try' /' __except' jako czegoś innego niż system zgłaszania awarii, podczas gdy często można odzyskać dane z wyjątku w bloku 'try' /' catch'. –

+2

@David: Zgadza się. '__try' i' __except' to stricte oparte na C API/ABI. –

+0

Jedyne dobre zastosowania dla tego, co widziałem, zajmowały się tym, co stanowiło błędy w samym systemie Windows (takie jak to, co działo się, gdy próbowano skopiować urządzenie). Prawdopodobnie zawsze wskazują gdzieś, gdzie system Windows powinien przechwycić wyjątek i przetłumaczyć go na błąd. (Sposób, w jaki działają, jest również przerażający i bardzo specyficzny dla x86 ...) –

38

Są to dwie różne rzeczy: bardzo różne:. try/catch to znajome słowa kluczowe C++, które znasz. __try/__except służy do przechwytywania wyjątków SEH. Wyjątki zgłaszane przez sam system Windows, na przykład DivisionByZero lub AccessViolation. Jest on dobrze opisany w MSDN Library article.

Można go również użyć do przechwycenia wyjątku C++, ponieważ wykorzystuje funkcję Windows SEH. Nie można jednak pobrać z niego obiektu wyjątku wyrzuconego, więc będzie zerowy kontekst, jeśli rzeczywiście chcemy obsługiwać wyjątek. Które jest szaleństwem. Podejście numer jeden polega na tym, aby nigdy nie wychwycić wyjątków SEH, zawsze są one obrzydliwe. Jeśli musisz poślubić dwa, użyj _set_se_translator(), aby przekonwertować wyjątek SEH do wyjątku C++.

+3

+1 dla MSDN ref. –

6

__try/__except jest przeznaczony do wywoływania kodu Win32 C, który nie obsługuje wyjątków, ale używa strukturalnego mechanizmu obsługi kodu błędu/obsługi. __try/__except tłumaczy błędy C na blok wyjątków podobny do C++ try/catch.

Aby uzyskać więcej informacji, zobacz this MSDN article.

+0

+1 dla MSDN ref –

4

Standardowe C++ używa bloków try/catch, więc polecam ich używanie, jeśli potrzebujesz "standardowego" mechanizmu wyjątku, opartego na standardowej bibliotece C++.

Jeśli jednak planowane jest korzystanie z funkcji obsługi wyjątków strukturalnych w pakiecie Windows SDK (patrz here), należy użyć __try/__except.

+0

-1: STL nie ma absolutnie nic wspólnego z obsługą wyjątków. –

+2

STL ma absolutnie coś wspólnego z obsługą wyjątków: std :: exception, który jest zalecaną klasą podstawową dla wyjątków, nawet jeśli nie jest to obowiązkowe. –

+0

'std :: exception' nie jest klasą STL. –

1

Po rzuceniu czegoś nie masz już większego wyboru, jak go złapać. Jeśli rzucisz wyjątki C++ (np., z throw), a następnie użyj try/catch. Jeśli rzucisz wyjątki Windows (tj. Z RaiseException), użyj __try/__except. Próba ich zmieszania po prostu doda niepotrzebnych kłopotów do twojego życia.

+3

Ale nigdy nie powinieneś wyrzucać wyjątków okien, ponieważ nie rozwijają stosu. –

Powiązane problemy