end Proc; begin Proc; Statement_2;
P := new Node; -- Может возбуждаться исключение
Statement_1; -- Пропускается, если возбуждено исключение
exception
when Storage_Error =>
-- Обработчик исключения
end Proc; begin Proc; Statement_2; — Пропускается, если исключение распространилось
из Proc
exception
when Storage_Error =>
-- Обработчик исключения
end Main;
После последнего исполняемого оператора подпрограммы ключевое слово exception вводит последовательность обработчиков исключений — по одному для каждого вида исключений. Когда возбуждается исключение, процедура покидается, и вместо нее выполняется обработчик исключения. Когда обработчик завершает свою работу, выполняется нормальное завершение процедуры. В приведенном примере программа выделения памяти может породить исключительную ситуацию Storage_Error, в этом случае Statement_1 пропускается, и выполняется обработчик исключения. После завершения обработчика и нормального завершения процедуры главная программа продолжается с оператора Statement_2.
Семантика обработки исключений предоставляет программисту большую гибкость в управлении обработкой исключительных ситуаций:
• Если исключительная ситуация не обработана внутри процедуры, попытка ее выполнения оставляется, и исключительная ситуация возбуждается снова в точке вызова. При отсутствии обработчика в Proc исключение повторно было бы возбуждено в Main, оператор Statement_2 был бы пропущен и выполнен обработчик в Main.
• Если исключительная ситуация возбуждается во время выполнения обработчика, обработчик оставляется, и исключение возбуждается снова в точке вызова.
• У программиста есть выбор: возбудить то же самое или другое исключение в точке вызова. Например, мы могли бы перевести предопределенное исключение типа Storage_Error в исключение, определенное в прикладной программе. Это делается с помощью оператора rais в обработчике: