Metody realizacji języków programowania/MRJP Wykład 10: Różnice pomiędzy wersjami
mNie podano opisu zmian |
|||
Linia 14: | Linia 14: | ||
=== Składnia === | === Składnia === | ||
Dla ustalenia uwagi przyjmiemy składnię C++ (składnia | Dla ustalenia uwagi przyjmiemy składnię C++ (składnia Javy jest w tej kwestii bardzo podobna) | ||
Zgłoszenie wyjątku | |||
==== Zgłoszenie wyjątku ==== | |||
throw <wyrażenie> | throw <wyrażenie> | ||
Obsługa wyjątków | ==== Obsługa wyjątków ===== | ||
try { | try { | ||
<instrukcje> | <instrukcje> | ||
Linia 57: | Linia 58: | ||
} | } | ||
catch E1 { ... } | catch E1 { ... } | ||
} | |||
catch E2 { ... } | catch E2 { ... } | ||
* rozpoznanie typu zgłoszonego wyjątku | * rozpoznanie typu zgłoszonego wyjątku |
Wersja z 10:54, 20 wrz 2006
Wyjątki
- Pojęcie wyjątek oznacza błąd (nietypową, niepożądaną
sytuację).
- Obsługa wyjątków oznacza reakcję programu na wykryte błędy.
- Funkcja, która napotkała problem zgłasza (rzuca)
wyjątek.
- Wyjątek jest przekazywany do miejsca wywołania funkcji, gdzie
może być wyłapany i obsłużony albo przekazany wyżej. Innymi słowy poszukiwania bloku obsługi wyjątku dokonywane są połańcuchu DL.
- Przy wychodzeniu z funkcji i bloków usuwane są obiekty automatyczne.
Składnia
Dla ustalenia uwagi przyjmiemy składnię C++ (składnia Javy jest w tej kwestii bardzo podobna)
Zgłoszenie wyjątku
throw <wyrażenie>
Obsługa wyjątków =
try { <instrukcje> } catch(<parametr 1>) { <obsługa wyjątku 1> //... } catch(<parametr n>) { <obsługa wyjątku n> }
Semantyka
- Gdy któraś z instrukcji w części try przekazała
wyjątek, przerywamy wykonanie tego ciągu i szukamy catch z odpowiednim parametrem.
- Jeśli znajdziemy, to wykonujemy obsługę tego wyjątku, a po jej
zakończeniu instrukcje po wszystkich blokach catch.
- Jeśli nie znajdziemy, przechodzimy do miejsca wywołania
(usuwając obiekty automatyczne bieżącej funkcji) i kontynuujemy poszukiwanie.
- Jeśli nie znajdziemy w żadnej z aktywnych funkcji, wykonanie
programu zostanie przerwane.
Implementacja obsługi wyjątków
Obsługę wyjątków można zrealizować na wiele różnych sposobów. Bardzo istotne jest jednak to, aby narzut (dodatkowy czas wykonania programu i zużyta pamięć) przy normalnym (tj. bez wystąpienia wyjątków) wykonaniu programu był minimalny, a w miarę możności zerowy. Z tego punktu widzenia realizacje wymagające wykonania dodatkowych czynności na początku i końcu bloku try można uznać za nieefektywne.
Bliższe spojrzenie na semantykę wyjątków, ujawnia, że w momencie zgłoszenia wyjątku muszą zostać wykonane następujące czynności:
- stwierdzenie, czy nastąpiło ono wewnątrz bloku try
- identyfikacja odpowiednich bloków try - moze być więcej niż jeden, np.
try { f(); try { g(); // tu wyjątek } catch E1 { ... } } catch E2 { ... }
- rozpoznanie typu zgłoszonego wyjątku
- próba dopasowania do typu wyjątku jednego z bloków catch
- w wypadku powodzenia wykonanie tego bloku
- w przeciwnym wypadku przekazanie wyjątku w górę DL