Характеристика исключений
1. Полнота исключений — на любое исключение должна быть предусмотрена реакция исполнителя (компьютера).
2. Минимальность возмущений — затраты на учет чрезвычайных ситуаций должны быть минимальны.
3. Минимальность повреждений — ущерб при возникновении исключений должен быть минимален.
С теоретической точки зрения требование полноты реализовать невозможно, но практический подход позволяет выделить перечень исключений, которые могут предугадать авторы языка, и дополнительный перечень, предсказываемый разработчиками некоторого программного обеспечения (ПО). Авторы языка программирования опираются на исследование комплекса проблем, выявленных программистским сообществом при написании любых компьютерных программ. Разработчики ПО исходят из своего опыта по созданию (и эксплуатации) конкретных программных приложений.
Таким образом, очерчивают круг возможных неприятностей, на которые целесообразно отреагировать.Минимальность возмущений можно интерпретировать следующим образом: желательно, чтобы заботы об исключениях в минимальной степени сказывались на всех этапах создания и использования программных продуктов.
524 |
Глава 17. Аппарат исключений |
Обсуждая минимальность повреждений, говорят о способности аппарата как можно раньше и как можно точнее реагировать на исключение, чтобы предотвратить дальнейшее разрушение программы и данных в аварийных условиях. Исключение — это необычное, аварийное событие (исключительная ситуация), которое обнаруживается аппаратно или программно и требует специальной обработки (обработки исключения). Обработка производится обработчиком исключения (ловушкой исключения). Различают предопределенные и определяемые программистом исключения. Предопределенные исключения встроены в язык программирования, они фиксируют ошибки ограничений, переполнения, деления на нуль, исчезновение порядка. Их полнота гарантирует, что при нарушении любого языкового требования создается конкретное предопределенное исключение. Минимальность возмущений проявляется в возникновении предопределенного исключения без указания программиста. Например, в языке Ada, который справедливо считают самым надежным языком программирования, предопределенные исключения образуют: ? ошибка ограничения — Constraint_Error — возникает при нарушении допустимого диапазона значений или индексов; ? программная ошибка — Program_Error — возникает при некорректном поведении программы (в языке выделяют два случая: Bounded_Error — выход поведения за допустимые границы; Erroneous_Execution — проявление причин, ведущих к неправильному выполнению); ? недостаток памяти — Storage_Error — возникает при нехватке памяти для размещения динамических объектов; ? ошибка взаимодействия — Tasking_Erroi— возникает при нарушениях во взаимодействии асинхронных (параллельных) процессов. Программная ошибка может возникнуть во множестве ситуаций, где программа некорректна, но компилятор не может выявить это во время компиляции. К таким ситуациям относятся: возможность достижения конца функции без выполнения операции return; проверка доступности для ссылочных типов во время выполнения. Следствия использования предопределенных исключений: 1. Программист не должен разрабатывать возникновение таких исключений. 2. Соответствующие указания не загромождают программу. 3. Соответствующие проверки реализуются аппаратурой или авторами компиляторов. Пример. Рассмотрим блок (составной оператор) с меткой В: -- это обозначение метки declare A : Float; -- в декларативном разделе объявляются локальные переменные begin A := X * X; Y := A * EXP(A); -- возможно переполнение; -- можно перекрыть реакцию на ошибку exception -- ловушка исключений; when Constraint_Error => Y := Float'Last; -- наибольшее вещественное Put ("Переполнение при вычислении Y в блоке В"); end B; |
Характеристика исключений |
525 |
Здесь ловушка исключений — это определенная программистом реакция на предопределенное исключение Constraint_Error (она может отсутствовать, так как в системе есть стандартная ловушка). Определяемые исключения расширяют возможности аппарата исключений. Они ориентированы на ошибки, которые не могли предугадать авторы языка, но о которых знают разработчики конкретных программных систем. Эти исключения явно определяются программистом с помощью объявления. Например, в языке Ada определяемые исключения декларируются программистом с помощью следующих объявлений: < ИмяИсключения > : exception; Пример. Объявим исключения: Объект_Пуст, Ошибка_В_Данных : exception; Мы создали описания двух исключений. Программист должен задать хотя бы одну реакцию на объявленное исключение (построить ловушку — тело, реализацию обработчика исключения). Само определяемое исключение возникает по оператору raise в программе. Этот оператор записывает программист, предваряя его «запуск» анализом возможной ситуации. Например, в результате оператора if then raise Ошибка_В_Данных end if; возникает исключение Ошибка_В_Данных. При возникновении исключения исполнитель переводится в режим обработки исключения: 1. Происходит распространение исключения (ищется подходящая ловушка); 2. Выполняется «реакция на исключение», описанная в найденной ловушке. Обычно все обработчики (ловушки) исключений группируются в начале илив конце большой программы или подпрограммы, где может произойти исключительная ситуация. Типичной в этом отношении является структура языка Ada, где обработчики «прижимаются» к закрывающей скобке какого-нибудь блока: procedure Sub is Bad_Data_Value: exception; --другие объявления в Sub begin -- операторы, выполняемые при нормальном ходе Sub exception when Bad_Data_Value => -- обработчик для некорректных значений данных when Constraint_Error => -- обработчик для предопределенного исключения Constraint_Error when others => -- обработчик для всех других исключений end Sub; В данном примере обработчик исключений (он начинается с ключевого слова exception) располагается в конце раздела операторов процедуры Sub. Внутри обработчика размещено несколько вариантов обработки. Каждый вариант начинается с ключевого слова when, за которым записывается имя анализируемого исключения. Обработчик может предусматривать реакцию на несколько исключений. Форма записи такого обработчика имеет вид: |
526 |
Глава 17. Аппарат исключений |
exception -- начало ловушки; when Program_Error | Был_Невежлив => Put ("Извинись и исправь!"); when ... when others => Put ("Фатальная ошибка!"); end; Видим, что в отдельном варианте выбора имена исключений перечисляются через вертикальную черту. Выбор others в перечне вариантов должен быть последним. Он конкретизирует реакцию на все оставшиеся исключения. |