Р.У. Себеста - Основные копцепции языков программирования (2001) (1160794), страница 144
Текст из файла (страница 144)
В одном случае оценка равна ! 00: в другом — достигается конец входных данных. Заметим, что обработчик для исключительной ситуации ЯОВЯСН1РТНАН6Е позволяет продолжать выполнение программы при неправильных оценках лаже несмотря иа то, что встроенный обработчик для этой исключительной ситуации, замещаемый данной программой, может привести к прекращению ее выполнения. 13.2.6. Оценка Язык РЬ/1 предоставляет программисту мощные средства лля распознавания и обработки исключительных ситуаций. За высокий уровень их гибкости, однако, приходится платить.
Основным примером этого является динамическое связывание исключительных ситуаций с их обработчиками, которое порождает трудности при написании и чтении программ, связанные с проблемами динамической области видимости. Действительно, область видимости обработчика исключительной ситуации является динамической, значит, невозможно определить по листингу, какое связывание происходит в любой заданной точке программы. Вследствие динамического связывания легко получить обработчик, непреднамеренно используемый для некоей исключительной ситуации, в действительности синтаксически далекой от заланной н полностью неприемлемой в данном случае. Рассмотрим следующий простой фрагмент кода: (ЯОВЯСН1РТНАН6Е): ВЕ61Н) ОХ ЯОВЯСН1РТНАН6Е ВЕ61Н; РОТ ЫЯТ('ОШИБКА — НЕВЕРНЫЙ ИНДЕКС В МАССИВЕ ЯОВЯУМ')) 60 ТО Р1Х1Т) ЕНО; ОН ЯОВЯСН1РТНАХСЕ ВЕ61Н) РОТ ЫЯТ('ОШИБКА — НЕВЕРНЫЙ ИНДЕКС В МАССИВЕ ВЬК '); 60 ТО ОО1Т( ЕНО) ЬАВЕЬ1: В1К(1, .т, К) = ЯОМ; Если в код, расположенный между двумя обработчиками исключительной ситуации ЯОВЯСН1РТНАМОЕ, оказывается включенным оператор 6О ТО ЬАВЕЬ1, то первый обработчик выполняется, если исключительная ситуация возникает при присваивании значений элементу массива ВЬК.
Это может привести к активизации неверного обработчика, что вызывает (по крайней мере) большое недоумение пользователя (он может решить, что ошибка произошла в массиве ЯОВЯОМ, а не в массиве ВЬК). Глава ! 3. Обработка исключительных ситуаций Другая серьезная проблема является следствием гибкости правил продолжения выполнения программ в языке Р) '!.
Они трудны для реазизацин. пагубно сказываются на читабельности, как и оператор сосо. кроме того. трудно научиться использовать нх эффективно. Поскольку механизм обработки исключительных ситуаций в языке Р!У1 представляется слишком сложным. разработчики других языков не стати его копировать. Более ограниченная модель была предло;кена в 1975 году в работе (Оообепоцяй. ! 975). в которой исключительные ситуации статически связывазись с их обработчиками. Еше более ограниченная молель была описана в языке СШ в середине 1970-х голов Жзкоч е! а1..
1984). В более поздних языках способы обработки исключительных ситуаций, по крайней мере частично. основаны на способах. предложенных в языке СШ. 13.3. Обработке исключительных ситуаций в языке Ада Обработка исключительных ситуаций в языке Аба — мошное средство для построения более надежных программных систем. Она включает в себя то лучшее, что есть в обработке исключительных ситуаций в языках РЬ'1 и СШ. ) З.ЗЛ. Обработчики исключительных ситуаций Обработчики исключительных ситуаций обычно являются локальными по отношению к коду, в котором возбуждается исключительная ситуация. Поскольку это обеспечивает их той же самой средой ссылок.
параметры лля обработчиков исключительных ситуаций не обязательны. а потому и не допускаются. Обработчики исключительных ситуаций имеют следуюший общий вид: иьеп выбор ситуации !! выбор сит,ации ! => последовательность операторов Здесь скобки являются метаснмволами. т.е. их содержимое может либо отсутствовать, либо повторяться любое колнчество раз. Выражение выбор ситуации имеет вид: имя исключительной ситуации ! ос!зека Имя исключительной ситуации указывает конкретную исключительную ситуацию или ситуации, для обработки которых предназначен обработчик.
Последовательность операторов — это тело обработчика. Зарезервированное слово овЬехв указывает на то. что обработчик предназначен для обработки любых исключительных ситуаций. не названных ни в одном локальном обработчике. Обработчики исключительных ситуаций могут быть включены в блоки или в тела полпрограмм. пакетов или залач. Независимо от блока или модуля, в котором они появляются, обработчики помещаются вместе в раздел ехсервдоп. который должен находиться в конце блока или модуля.
Например. обычный вид раздела ехсервйоп показан в следуюшем фрагменте кода: Ьедйп блок или тело модуля ехсерсдоп 13.3. Обработка исключительных ситуаций в языке Аба иЬеп ехсертьоп паже 1 => -- первый обработчик-- мЬеп ехсерсдоп паже 2 => второй обработчик -- дрУгие обработчики-- епс11 Любой оператор, допустимый в блоке или модуле, в котором появляется обработчик исключительных ситуаций, также допустим и в обработчике. 13.3.2. Связывание исключительных ситуаций с обработчиками Когда блок или модуль, возбуждающий исключительную ситуацию, содержит обработчик для этой исключительной ситуации, она может статически связываться с этим обработчиком. Если исключительная ситуация возбуждается в блоке или модуле, не имеющем обработчика для этой конкретной ситуации, то она передается в некоторый другой блок или модуль.
Способ, которым исключительные ситуации передаются в другие модули, зависит от сущности программы, в которой возникает исключительная ситуация. Когда исключительная ситуация возбуждается в процедуре, либо при выполнении ее объявлений, либо при выполнении ее тела, а процедура не имеет обработчика лля этой ситуации, такая исключительная ситуация неявно передается в вызывающий программный модуль в точку вызова. Этот подход отражает философию разработки, заключающуюся в том, что передача исключительной ситуации должна отслеживаться через путь управления (через динамических предков), а не через статических предков. Если вызывающий модуль, в который была передана исключительная ситуация, также не имеет обработчика для нее, она передается дальше в модуль, вызвавший данный модуль.
Это продолжается при необходимости вплоть до главной программы. Если исключительная ситуация была передана главной программе, а ее обработчик все еше не найден, выполнение программы завершается. С точки зрения обработки исключительных ситуаций блок в языке Ас)а рассматривается как лишенная параметров процедура, "вызываемая" родительским блоком, когда управление выполнением достигает первою оператора в блоке. Когда в блоке возбуждается исключительная ситуация (либо в объявлениях, либо в выполняемых операторах), а блок не имеет обработчика для нее, эта исключительная ситуация передается в следующую охватывающую ее область видимости, которая является кодом, "вызвавшим" данную процедуру.
Точка, в которую передается исключительная ситуация, — это просто оператор, следующий за концом блока, в котором эта ситуация возникла, называющийся точкой "возврата". Когда исключительная ситуация возбуждается в теле пакета, которое не имеет обработчика для данной исключительной ситуации, такая ситуация передается в раздел объявлений модуля, содержащего объявление пакета. Если пакет оказался библиотечным модулем (который компилируется отдельно), то выполнение программы завершается.
Если исключительная ситуация возбуждается на внешнем уровне в теле задачи, и эта задача содержит обработчик лля данной исключительной ситуации, то этот обработчик выполняется, а задача помечается как завершенная. Если задача не содержит обработчика для данной исключительной ситуации, то она просто помечается как выполненная, а исключительная ситуация никуда не передается. Механизм управления задачей слишком Глава 13. Обработка исключительных ситуаций сложен, для того чтобы дать разумный и простой ответ на вопрос, куда должны передаваться ее необработанные исключительные ситуации. Исключительные ситуации также могут возникать при выполнении разделов объявлений в подпрограммах.
блоках. пакетах и задачах. Предположим. что некая функция вызывается лля того, чтобы инициализировать переменную в операторе ее объявления, как показано ниже: ркоаесЫке ЯТЧЕЯ Ев ООЯПЕХТ ГЬОХ : ГЬОАТ := ОЕТ ГЬОХ; )задал епа КТЧЕПг Допустим, что ОЕТ ГЬОХ вЂ” зто функция без параметров. Если функция ОЕТ ГЬОХ возбуждает и передает исключительную ситуацию в модуль, вызвавший ее. то эта исключительная ситуация возбуждается вновь в этом объявлении. Размещение переменных в памяти во время выполнения объявлений также может возбудить некую исключительную ситуацию.
Когда исключительные ситуации возникают во время выполнения объявлений процедур, пакетов и блоков, они передаются точно так же, как если бы исключительная ситуация возбудилась в соответствующем разделе кода. Если это происхолит в задаче, она помечается как завершенная, дальнеЯшее выполнение объявлений переменных прекращается, и возбуждается встроенная исключительная ситуация ТАБК1ХО ЕЯЯОП в точке активизации задачи.
13.3.3. Прсздязлжвние Выполнение блока или модуля, возбудившего исключительную ситуацию, вместе с выполнением всех модулей. в которые эта ситуация передавалась, но не обрабатывалась там, всегда прекращается. Управление никогда не возвращается неявно в возбудившиЯ исключительную ситуацию блок или модуль после ее обработки. Управление просто передается оператору, следующему за разделом ехаерсеоп, который всегда находится в конце блока или модуля. Этот приводит к немедленному возврату на наивысшиЯ уровень управления. Для того чтобы решить, с какого места может продолжаться выполнение программы после выполнения обработчика исключительноЯ ситуации в программном модуле, команда по разработке языка Ада имела небольшой выбор, поскольку по требованиям спецификации языка Аба (Оерапшепг оГ Оденсе, 1980а) программные модули, возбудившие исключительную ситуацию, могли продолжать свое выполнение или возобновлять ею. Однако в случае блока оператор можно попытаться выполнить снова после того, как он возбудил исключительную ситуацию и она была обработана.
Предположим, что некий оператор, который может возбудить исключительную ситуацию, и ее обработчик помещены в блок, находящийся внутри цикла. Следующий пример фрагмента кода, получающего с клавиатуры четыре целых числа из требуемого диапазона, иллюстрирует этот вид структуры; Туре АОЕ ТУРЕ Ев тапде 0..125З Сузэе АОЕ ЬТЯТ ТУРЕ з.е актау (1..4) оЕ АОЕ ТУРЕ," 13.3. Обработка исключительных ситуаций в языке Ада рас)саде АСЕ 10 Дв пен 1НТЕСЕК 10 (А6Е ТУРЕ) иве АСЕ 10; АСЕ 115Т : АСЕ ЫЯТ ТУРЕ; Ьеддп Еок АСЕ СОРНТ Дп 1..4 1оор 1оор -- цикл для повторного ввода при возникновении исключительной ситуации ЕХСЕРТ ВЬК: Ьедхкп -- инкапсулирование обработки исключительной ситуации РОТ Ы'нЕ("Введите целое число в диапазоне 0..125"]; СЕТ (АСЕ ЫЯТ (АСЕ СОР()Т) ) ) ехдс1 ехсерсдоп нЬеп РАТА ЕККОК => -- Введенная строка не является числом РОТ ЫНЕ(5йеверное числовое значение"); РОТ ~1НЕ("Пожалуйста, попробуйте снова"); нЬеп СОНЯТВА1(ЧТ ЕККОК => -- Введенное значение < 0 или > 125 РОТ ЫНЕ("Число выходит за пределы диапазона"); РОТ ЫНЕ("Пожалуйста, попробуйте снова" ); епг( ЕХСЕРТ ВЬК; епй 1оор; -- последний оператор бесконечного цикла -- для повторного ввода, когда возникает исключительная ситуация епй 1оор; -- конец цикла АСЕ СООНТ |п 1..4 Управление остается во внутреннем цикле, содержащем только блок, пока на входе не будет получено правильное число.