try-except – příkaz (C)
Specifické pro Microsoft
Tento try-except
příkaz je rozšířením jazyka C od Microsoftu, které aplikacím umožňuje získat kontrolu nad programem, když dojde k událostem, které obvykle ukončují provádění. 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.
Výjimky můžou být založené na hardwaru nebo softwaru. I když se aplikace nemůžou úplně zotavit z výjimek hardwaru nebo softwaru, strukturované zpracování výjimek umožňuje protokolovat a zobrazovat informace o chybách. Je užitečné zachytit vnitřní stav aplikace, který pomáhá diagnostikovat problém. Zejména je užitečné pro občasné problémy, které se nesnadně reprodukují.
Syntaxe
try-except-statement
:
__try
compound-statement
__except (
expression
)
compound-statement
Složený příkaz za klauzulí __try
je strážený oddíl. Složený příkaz za __except
klauzulí je obslužná rutina výjimky. Obslužná rutina určuje sadu akcí, které se mají provést, pokud je při provádění strážené části vyvolána výjimka. Provádění pokračuje následujícím způsobem:
Chráněná část je spuštěna.
Nedojde-li za běhu chráněné části k žádné výjimce, pokračuje běh programu příkazem za klauzulí
__except
.Pokud dojde k výjimce během provádění stráženého oddílu nebo v jakékoli rutině volání strážených oddílů,
__except
výraz se vyhodnotí. Vrácená hodnota určuje způsob zpracování výjimky. Existují tři možné hodnoty:EXCEPTION_CONTINUE_SEARCH
: Výjimka se nerozpozná. Pokračujte ve vyhledávání zásobníku pro obslužnou rutinu, nejprve pro obsahujícítry-except
příkazy a potom pro obslužné rutiny s další nejvyšší prioritou.EXCEPTION_CONTINUE_EXECUTION
: Výjimka se rozpozná, ale zavře. Program bude pokračovat tam, kde k výjimce došlo.EXCEPTION_EXECUTE_HANDLER
Výjimka se rozpozná. Přeneste řízení do obslužné rutiny výjimky spuštěním složeného__except
příkazu a pak pokračujte v provádění v okamžiku, kdy došlo k výjimce.
__except
Vzhledem k tomu, že se výraz vyhodnotí jako výraz jazyka C, je omezen na jednu 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.
Poznámka:
Strukturované zpracování výjimek funguje se zdrojovými soubory jazyka C a C++. Není ale speciálně určená pro jazyk C++. V případě přenosných programů C++ by se mělo místo strukturovaného zpracování výjimek používat zpracování výjimek C++. Mechanismus zpracování výjimek jazyka C++ je také mnohem flexibilnější, protože dokáže zpracovat výjimky libovolného typu. Další informace naleznete v tématu Zpracování výjimek v referenční dokumentaci jazyka C++.
Každá rutina v aplikaci může mít vlastní obslužnou rutinu výjimky. Výraz __except
se provede v oboru __try
textu. Má přístup k místním proměnným deklarovaným tam.
Klíčové __leave
slovo je platné v rámci try-except
bloku příkazu. Účinek __leave
je přeskočit na konec try-except
bloku. Provádění se obnoví po ukončení obslužné rutiny výjimky. goto
Příkaz se dá použít k dosažení stejného výsledku, ale goto
příkaz způsobí odvíjení zásobníku. Příkaz __leave
je efektivnější, protože nezahrnuje odvíjení zásobníku.
Ukončení try-except
příkazu pomocí longjmp
funkce runtime se považuje za neobvyklé ukončení. Není to právní skočit do __try
prohlášení, ale je to legální přeskočit z jednoho. Obslužná rutina výjimky není volána, pokud se proces ukončí uprostřed provádění try-except
příkazu.
Příklad
Tady je příklad obslužné rutiny výjimky a obslužné rutiny ukončení. Další informace o obslužných rutinách ukončení najdete v části try-finally
příkaz (C).
.
.
.
puts("hello");
__try {
puts("in try");
__try {
puts("in try");
RAISE_AN_EXCEPTION();
} __finally {
puts("in finally");
}
} __except( puts("in filter"), EXCEPTION_EXECUTE_HANDLER ) {
puts("in except");
}
puts("world");
Tady je výstup z příkladu s komentářem přidaným vpravo:
hello
in try /* fall into try */
in try /* fall into nested try */
in filter /* execute filter; returns 1 so accept */
in finally /* unwind nested finally */
in except /* transfer control to selected handler */
world /* flow out of handler */
END Microsoft-specific