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

       

Проблемы с областью видимости при обработке исключений определяемых пользователем


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

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

Рассмотрим следующий пример:

with Ada.Text_IO; use Ada.Text_IO;

procedure Demo is

procedure Problem_In_Scope is

Cant_Be_Seen : exception; begin raise Cant_Be_Seen; end Problem_In_Scope;

begin

Problem_In_Scope;

exception

when Cant_Be_Seen => Put("just handled an_exception"); end Demo;



Этот пример не корректен.

Проблема в том, что область видимости исключения Cant_Be_Seen

ограничивается процедурой Problem_In_Scope, которая, собственно и является источником этого исключения.

То есть, исключение Cant_Be_Seen не видимо и о нем ничего не известно за пределами процедуры Problem_In_Scope.

Поэтому, это исключение не может быть точно обработано процедурой Demo.

Решить эту проблему можно использованием опции others в обработчике исключений внешней процедуры Demo:

with Ada.Text_IO; use Ada.Text_IO;

procedure Demo is

procedure Problem_In_Scope is

Cant_Be_Seen : exception; begin raise Cant_Be_Seen; end Problem_In_Scope;

begin

Problem_In_Scope;

exception

when others => Put("just handled some exception"); end Demo;

Другая проблема возникает тогда, когда в соответствии с правилами области видимости, исключение, описываемое в одной процедуре, перекрывает (или прячет) исключение, описываемое в другой процедуре:

with Ada.Text_IO; use Ada.Text_IO;

procedure Demo is

Fred : exception; -- глобальное исключение

------------------------------------ procedure P1 is

begin

raise Fred; end P1;

------------------------------------ procedure P2 is

Fred : exception; -- локальное исключение

begin

P1;

exception

when Fred => Put("wow, a Fred exception"); end P2; ------------------------------------

begin

P2;

exception

when Fred => Put("just handled a Fred exception"); end Demo;

<


Выводом такой процедуры будет "just handled a Fred exception". Исключение, обрабатываемое в процедуре P2, будет локально описанным исключением. Такое поведение подобно ситуации с областью видимости обычных переменных.

Для решения этой проблемы, процедуру P2 можно переписать следующим образом:

------------------------------------ procedure P2 is

Fred : exception;

begin

P1;

exception

when Fred => -- локальное исключение Put("wow, an_exception");

when Demo.Fred => -- "более глобальное" исключение Put("handeled Demo.Fred exception"); raise; end P2;

Теперь, обработчик исключения процедуры P2

выдаст сообщение "handeled Demo.Fred exception" и, с помощью инструкции raise, осуществит передачу исключения Demo.Fred в обработчик исключения процедуры Demo, который, в свою очередь, выдаст сообщение "just handled a Fred exception".


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