Ада-95. Компилятор GNAT

       

Распространение исключений


Для того, чтобы точно знать в каком месте должен быть расположен соответствующий обработчик исключения, необходимо понимать как при возникновении исключения, во время работы программы, происходит поиск обработчика.

Этот процесс поиска называется распространением исключений.

Если исключение не обрабатывается в подпрограмме в которой это исключение возникло, то оно распространяется в подпрограмму которая вызвала текущую подпрорамму (на уровень выше). После чего, обработчик исключения ищется в вызвавшей подпрограмме.

Если обработчик исключения не найден, то исключение распространяется дальше (еще на уровень выше). Это продолжается до тех пор пока не будет найден обработчик возникшего исключения или не будет достигнут уровень выполнения текущей задачи (наивысший уровень).

Если в случае достижения уровня выполнения текущей задачи (то есть наивысшего уровня) обработчик исключения не будет найден, то текущая задача будет аварийно завершена (другими словами, абортирована).

Если выполняется только одна задача, то библиотека времени выполнения Ады выполняет обработку возникшего исключения и аварийно завершает выполнение всей программы (другими словами, абортирует выполнение программы).

procedure Exception_Demo is

--------------------------------- procedure Level_2 is

-- здесь нет обработчика исключений begin raise Constraint_Error; end Level_2;

--------------------------------- procedure Level_1 is

begin

Level_2; exception

when Constraint_Error => Put("exception caught in Level_1"); end Level_1;

begin

Level_1;

exception

when Constraint_Error => Put("exception caught in Exception_Demo"); end Exception_Demo;

После запуска этой программы будет выдано только сообщение "exception caught in Level_1".

Следовательно, обработанное исключение не распространяется дальше.

Модифицируем процедуру Level_1 поместив инструкцию raise в ее обработчик исключения.

Наш предыдущий пример будет иметь следующий вид:

procedure Exception_Demo is

--------------------------------- procedure Level_2 is

-- здесь нет обработчика исключений begin raise Constraint_Error; end Level_2;

--------------------------------- procedure Level_1 is

begin

Level_2; exception

when Constraint_Error => Put("exception caught in Level_1"); raise; -- регенерация текущего исключения; -- дает возможность другим подпрограммам -- произвести обработку возникшего -- исключения end Level_1;

begin

Level_1;

exception

when Constraint_Error => Put("exception caught in Exception_Demo"); end Exception_Demo;

<


Теперь, инструкция raise, помещенная в обработчик исключения, вызывает распространение исключения Constraint_Error на один уровень выше, то есть, к вызвавшей подпрограмме.

Таким образом, исключение может быть получено и соответствующим образом обработано в каждой подпрограмме иерархии вызовов.

Инструкцию raise очень удобно использовать в секции others

обработчика исключений:

. . .

exception

. . .

when others => raise; -- регенерация текущего исключения; -- дает возможность другим подпрограммам -- произвести обработку возникшего -- исключения end;

В этом случае, соответствующее исключение будет продолжать генерироваться и распространяться до тех пор, пока не будет обработано надлежащим образом.


Содержание раздела