Definiując funkcję można jawnie wypecyfikować, jakiego typu wyjątki mogą zostać zgłoszone, a nie obsłużone podczas jej wykonywania. Robi się to poprzez podanie frazy throw po liście parametrów, a przed średnikiem (w deklaracji) lub ciałem funkcji (w definicji). We frazie tej należy podać w nawiasach listę oddzielonych przecinkami typów wyjątków, jakie mogą być zgłoszone, a nie obsłużone:
// deklaracja int fun(double) throw(std::bad_alloc, PozaZakresem); // ... // definicja int fun(double x) throw(std::bad_alloc, PozaZakresem) { // ... }Fraza ta musi wystąpić zarówno w deklaracji, jak i w definicji funkcji.
Jeśli taka fraza została podana dla metody wirtualnej, to wszystkie wersje przesłaniające tę metodę w klasach pochodnych mogą tylko „odejmować” niektóre typy — te, dla których same zapewnią obsługę. Nie można natomiast w klasach potomnych rozszerzać listy możliwych typów wyjątków metody wirtualnej.
Brak specyfikacji wyjątków w definicji funkcji jest równoważny podaniu
throw( wszystkie_mozliwe_typy )natomiast fraza z pustą listą
throw()oznacza, że w danej funkcji nie powinny zdarzyć się żadne nie obsłużone sytuacje wyjątkowe.
Jeśli funkcja może zgłosić nieobsłużony wyjątek typu nie wymienionego na liście specyfikacji, to program i tak się skompiluje, choć dobry kompilator powinien wypisać stosowne ostrzeżenia. Ta niekonsekwencja spowodowana jest koniecznością zachowania zgodności z istniejącymi programami i bibliotekami.
Jeśli podczas wykonywania programu w pewnej funkcji nastąpi nieobsłużone zgłoszenie wyjątku typu nie wymienionego w jej specyfikacji wyjątków, to program kończy się wywołaniem funkcji unexpected, która z kolei woła funkcję terminate. Tak jak można, za pomocą set_terminate, „podstawić” własną wersję funkcji terminate, tak za pomocą set_unexpected można określić inną funkcję, która ma pełnić rolę funkcji unexpected.
T.R. Werner, 21 lutego 2016; 20:17