Программирование >>  Полиморфизм без виртуальных функций в с++ 

1 ... 122 123 124 [ 125 ] 126 127 128 ... 144


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

Первые реализации обработки исключений в том виде, который описан в ARM, начали появляться весной 1992 г.

16.2. Цели и предположения

При проектировании были сделаны предположения о то.м, что:

□ исключения используются преимущественно для обработки ошибок;

□ обработчики исключений встречаются реже, чем определения функций;

□ по сравнению с вызовами функций исключения возникают редко;

□ исключения - это понятие уровня языка, а не компилятора, и не стратегия обработки ошибок в узком смысле.

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

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

□ задумывалась не как простая альтернатива .механизму возврата - так предлагали некоторые, в особенности Дэвид Черитон (David Cheriton), - а как специальный механизм для поддержки построения отказоустойчивых систем;

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

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

На протяжении всей работы по проектированию возрастало влияние проектировщиков разнообразных систем и уменьшалось число предложений от сообщества пользователей языка. За прошедшее с тех пор время наибольшее воздействие на проектирование обработки исключений в С-ы- оказала работа по отказоустойчивым системам, начатая в университете Ньюкасла в Англии Брайаном Рэпделло.м и его коллега.ми и продолженная в других местах.

В процессе проектирования обработки исключений были выработаны приведенные ниже критерии.

1. Передача произвольного объема информации из точки, где возбуждено исключение, обработчику с сохранением данных о типе.

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

3. Гарантии того, что любое возбужденное исключение будет перехвачено каким-то обработчиком.



Цели и предположения

j 389

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

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

6. Механизм, допускающий взаимодействие с другими языками и особенно с С.

7. Простота использования.

8. Простота реализации.

Большая часть этих критериев была воплощена в жизнь, но третий и вось.мой принципы всегда оказывались либо требующими больпп1Х затрат, либо слишком ограничительны.ми, поэтому в результате мы лишь приблизились к их реализацин. Я считаю это неплохим результатом, принимая во внимание то, что обработка исключений - трудная задача, для решения которой программисту понадобится вся помощь, которую только можно получить. Чрез.мерно ревностный проектировщик языка мог бы включить средства или ограничения, которые лишь усложнили бы проектирование и реализацию отказоустойчивой систе.мы.

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

В какой-то момент отдельный модуль системы может отказать, и тогда ситуация будет решаться на более высоком уровне этой системы. Например, вызванная функция может сообщить о катастрофической ошибке вызывающей; процесс может завершиться аномально и порзить другому процессу разобраться с последствиями; процессор может обратиться за помощью к другому процессору. Компьютер может затребовать помощь у оператора-человека. Подчеркнем в связи с этим: обработку ошибок следует проектировать так, чтобы у относительно простой профаммы, пользующейся сравнительно несложны.ми средствами обработки исключений, был шанс выполнить свою задачу.

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

16.3. Синтаксис

Как обычно, синтаксису было уделено достаточное внимание, и в результате я остановился на не слишком лаконичном варианте, в котором было три ключевых слова и обилие скобок:

int f() {

try { начало try-блока

return g();

catch (xxii) { начало обработчика исключения



int g() {

...

if (что то случилось) throw xxiiO; возбудить исключение

Ключевое слово try, очевидно, избыточно, равно как и скобки {}, если только try-блок или обработчик не состоят из нескольких предложений. Например, совсем несложно было бы разрешить такой синтаксис:

int f() {

return g() catch (xxii) { не С++ error( ошибка в g(): xxii ); return 22;

Однако его так трудно объяснить, что я решил пойти на избыточность, дабы избавить персонал службы технической поддержки от вопросов запутавшихся пользователей. Из-за традиционной нелюбви пользователей С к новым ключевым словам я всячески пытался уйти от этого, но все схемы, которые приходили на ум, оказывались слишком хитроумными или сбивающими с толку. Так, я пробовал использовать одно слово catch и для возбуждения и для перехвата исключения. Это можно было бы сделать логически непротиворечиво, но объяснить такую схему я бы не взялся.

Слово throw было выбрано отчасти из-за того, что более очевидные слова raise и signal уже были заняты под функции из стандартной библиотеки С.

16.4. Группировка

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

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

сюда попадаем только тогда, когда случилось xxii error( ошибка в g(): xxii ); return 22;



1 ... 122 123 124 [ 125 ] 126 127 128 ... 144

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика