Sdílet prostřednictvím


try-except – příkaz

Specifické pro Microsoft

Následující syntaxe popisuje příkaz try-except:

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

Poznámky

Příkaz try-except je rozšířením jazyků C a C++ společností Microsoft, které umožňuje cílovým aplikacím získat kontrolu v případě, že dojde k událostem, které za normálních okolností ukončí běh programu.Tyto události jsou nazývány výjimkami a mechanismus, který se výjimkami zabývá, se nazývá strukturované zpracování výjimek.

Související informace naleznete v tématu Příkaz try-finally.

Výjimky mohou být hardwarové nebo softwarové.I v případech, kdy aplikace nemohou být zotaveny z hardwarových nebo softwarových výjimek, umožňuje strukturované zpracování výjimek zobrazit informace o chybě a zachytit vnitřní stav aplikace pro diagnostiku problému.To je užitečné zejména pro občasné problémy, které nelze snadno reprodukovat.

[!POZNÁMKA]

Strukturované zpracování výjimek funguje na architektuře Win32 pro zdrojové soubory jazyka C i C++.Pro jazyk C++ však není výslovně navržen.Větší přenositelnost kódu lze zajistit použitím zpracování výjimek jazyka C++.Zpracování výjimek jazyka C++ je také více flexibilní, jelikož dokáže zpracovat výjimky libovolného typu.Pro programy C++ je doporučeno použití mechanismu zpracování výjimek jazyka C++ (příkazy try, catch a throw).

Složený příkaz za klauzulí __try je tělem chráněné části.Složený příkaz po klauzuli __except je obslužnou rutinou výjimky.Obslužná rutina udává sadu akcí provedených v případě, že během provádění těla chráněné části dojde k vyvolání výjimky.Spuštění probíhá následujícím způsobem:

  1. Chráněná část je spuštěna.

  2. Nedojde-li za běhu chráněné části k žádné výjimce, pokračuje běh programu příkazem za klauzulí __except.

  3. Pokud k výjimce za běhu chráněné části nebo v jakékoliv rutině, kterou chráněná část zavolala, dojde, je vyhodnocen výraz__except (nazývaný výraz filtru) a jeho hodnota určuje, jak je výjimka zpracována.Existují tři hodnoty:

    EXCEPTION_CONTINUE_EXECUTION (–1)   Výjimka je ignorována.Program bude pokračovat tam, kde k výjimce došlo.

    EXCEPTION_CONTINUE_SEARCH (0)   Výjimka není rozpoznána.Program bude pokračovat v hledání obslužné rutiny v zásobníku, tedy nejprve odpovídající příkazy try-except, poté obslužné rutiny s druhou nejvyšší prioritou.

    EXCEPTION_EXECUTE_HANDLER (1)   Výjimka je rozpoznána.Řízení je převedeno na obslužnou rutinu událostí spuštěním složeného příkazu __except, poté běh programu pokračuje příkazy za blokem __except.

Jelikož je výraz __except vyhodnocován jako výraz jazyka C, je omezen na jedinou hodnotu, operátor podmíněného výrazu nebo operátor čárky.Je-li požadováno rozsáhlejší zpracování, může výraz zavolat rutinu, která vrátí jednu z výše uvedených tří hodnot.

Každá aplikace může obsahovat svou vlastní obslužnou rutinu výjimky.

Není povoleno přejít do příkazu __try, je však povoleno přejít mimo něj.Obslužná rutina výjimky není zavolána, je-li proces v průběhu provádění příkazu try-except ukončen.

Další informace naleznete ve článku znalostní báze Q315937 : POSTUPY: Zachycení přetečení zásobníku v aplikaci Visual C++.

Klíčové slovo __leave

Klíčové slovo __leave je platné pouze uvnitř chráněné části příkazu try-except a jeho účinkem je přechod na konec chráněné části.Běh programu pokračuje prvním příkazem za obslužnou rutinou výjimky.

Příkazem goto lze také přejít mimo chráněnou část a nesnižuje výkon jako v příkazu try-finally, protože nedochází k rozvíjení zásobníku.Je však doporučeno používat spíše klíčové slovo __leave namísto příkazu goto, protože tím lze snížit riziko programové chyby, je-li chráněný oddíl velký nebo složitý.

Vnitřní funkce strukturovaného zpracování výjimek

Strukturované zpracování výjimek poskytuje dvě vnitřní funkce, které lze použít spolu s příkazem try-except: GetExceptionCode a GetExceptionInformation.

Funkce GetExceptionCode vrací kód (32bitové celé číslo) výjimky.

Vnitřní funkce GetExceptionInformation vrací ukazatel na strukturu obsahující další informace o výjimce.Pomocí tohoto ukazatele lze přistoupit ke stavu počítače, v jakém byl v době výskytu hardwarové výjimky.Struktura je následující.

struct _EXCEPTION_POINTERS {
      EXCEPTION_RECORD *ExceptionRecord,
      CONTEXT *ContextRecord }

Typy ukazatelů _EXCEPTION_RECORD a _CONTEXT jsou definovány v souboru hlaviček EXCPT.H.

Funkci GetExceptionCode lze použít uvnitř obslužné rutiny výjimky.Funkci GetExceptionInformation však lze použít pouze uvnitř výrazu filtru výjimky.Informace, na které ukazuje, jsou obecně umístěny na zásobníku a ve chvíli, kdy je řízení převedeno na obslužnou rutinu výjimky, již nedostupné.

Vnitřní funkce AbnormalTermination je k dispozici uvnitř obslužné rutiny ukončení.Funkce vrátí hodnotu 0, je-li tělo příkazu try-finally ukončeno sekvenčně.Ve všech ostatních případech vrátí hodnotu 1.

Soubor EXCPT.H pro tyto vnitřní funkce definuje několik alternativních názvů:

GetExceptionCode je ekvivalentem klauzule _exception_code

GetExceptionInformation je ekvivalentem klauzule _exception_info

AbnormalTermination je ekvivalentem klauzule _abnormal_termination

Příklad

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

}

Výsledek

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

Specificka produktu Microsoft END

Viz také

Referenční dokumentace

Zápis obslužné rutiny výjimek

Strukturované zpracování výjimek (C/C++)

Klíčová slova jazyka C++