В вычислительной технике и программировании обработка исключений — это процесс реагирования на возникновение исключений — аномальных или исключительных условий, требующих специальной обработки — во время выполнения программы . В общем случае исключение нарушает нормальный поток выполнения и запускает заранее зарегистрированный обработчик исключений ; подробности того, как это делается, зависят от того , является ли это аппаратным или программным исключением и как реализовано программное исключение.
Исключения определяются различными уровнями компьютерной системы, и типичными уровнями являются прерывания, определяемые ЦП , сигналы , определяемые операционной системой (ОС) , исключения , определяемые языком программирования . Каждый уровень требует различных способов обработки исключений, хотя они могут быть взаимосвязаны, например, прерывание ЦП может быть преобразовано в сигнал ОС. Некоторые исключения, особенно аппаратные, могут обрабатываться настолько изящно, что выполнение может возобновиться с того места, где оно было прервано.
Определение исключения основано на наблюдении, что каждая процедура имеет предусловие , набор обстоятельств, при которых она завершится «нормально». [1] Механизм обработки исключений позволяет процедуре вызывать исключение [2] , если это предусловие нарушено, [1] например, если процедура была вызвана с ненормальным набором аргументов. Затем механизм обработки исключений обрабатывает исключение. [3]
Предварительное условие и определение исключения субъективны . Набор «нормальных» обстоятельств определяется исключительно программистом, например, программист может посчитать деление на ноль неопределенным, следовательно, исключением, или придумать какое-то поведение, например, возврат нуля или специального значения «ДЕЛЕНИЕ НА НОЛЬ» (обходя необходимость исключений). [4] Обычные исключения включают недопустимый аргумент (например, значение находится вне области действия функции ), [5] недоступный ресурс (например, отсутствующий файл, [6] ошибка сетевого диска, [7] или ошибки нехватки памяти [8] ), или то, что процедура обнаружила нормальное состояние, требующее специальной обработки, например, внимание, конец файла. [9] Социальное давление оказывает большое влияние на область действия исключений и использование механизмов обработки исключений, то есть «примеры использования, обычно встречающиеся в основных библиотеках, и примеры кода в технических книгах, журнальных статьях и онлайн-форумах для обсуждения, а также в стандартах кода организации». [10]
Обработка исключений решает проблему полупредикатов , поскольку механизм отличает нормальные возвращаемые значения от ошибочных. В языках без встроенной обработки исключений, таких как C, подпрограммам необходимо было бы сигнализировать об ошибке каким-то другим способом, например, общим кодом возврата и шаблоном errno . [11] Принимая широкую точку зрения, ошибки можно считать надлежащим подмножеством исключений, [12] а явные механизмы ошибок, такие как errno, можно считать (подробными) формами обработки исключений. [11] Термин «исключение» предпочтительнее термина «ошибка», поскольку он не подразумевает, что что-то не так — условие, рассматриваемое как ошибка одной процедурой или программистом, может не рассматриваться так другим. [13]
Термин «исключение» может вводить в заблуждение, поскольку его коннотация «аномалии» указывает на то, что возникновение исключения является ненормальным или необычным, [14] когда на самом деле возникновение исключения может быть нормальной и обычной ситуацией в программе. [13] Например, предположим, что функция поиска для ассоциативного массива выдает исключение, если ключ не имеет связанного значения. В зависимости от контекста, это исключение «отсутствие ключа» может возникать гораздо чаще, чем успешный поиск. [15]
Первая аппаратная обработка исключений была обнаружена в UNIVAC I в 1951 году. Арифметическое переполнение выполняло две инструкции по адресу 0, которые могли передавать управление или исправлять результат. [16] Программная обработка исключений, разработанная в 1960-х и 1970-х годах. Обработка исключений впоследствии широко применялась во многих языках программирования с 1980-х годов.
Не существует четкого консенсуса относительно точного значения исключения по отношению к оборудованию. [17] С точки зрения реализации оно обрабатывается идентично прерыванию : процессор останавливает выполнение текущей программы, ищет обработчик прерываний в таблице векторов прерываний для этого исключения или условия прерывания, сохраняет состояние и переключает управление.
Обработка исключений в стандарте IEEE 754 для чисел с плавающей точкой в целом относится к исключительным условиям и определяет исключение как «событие, которое происходит, когда операция над некоторыми конкретными операндами не имеет результата, подходящего для любого разумного приложения. Эта операция может сигнализировать об одном или нескольких исключениях, вызывая обработку по умолчанию или, если явно запрошено, альтернативную обработку, определенную языком».
По умолчанию исключение IEEE 754 является возобновляемым и обрабатывается путем замены предопределенного значения для различных исключений, например, бесконечности для исключения деления на ноль, и предоставления флагов состояния для последующей проверки того, произошло ли исключение (см. язык программирования C99 для типичного примера обработки исключений IEEE 754). Стиль обработки исключений, обеспечиваемый использованием флагов состояния, включает: первое вычисление выражения с использованием быстрой, прямой реализации; проверку того, не завершилось ли оно ошибкой, путем тестирования флагов состояния; а затем, при необходимости, вызов более медленной, более численно надежной реализации. [18]
Стандарт IEEE 754 использует термин «ловушка» для обозначения вызова пользовательской процедуры обработки исключений в исключительных условиях и является необязательной функцией стандарта. Стандарт рекомендует несколько сценариев использования для этого, включая реализацию нестандартной предварительной подстановки значения с последующим возобновлением, чтобы лаконично обрабатывать устранимые сингулярности . [18] [19] [20]
Поведение обработки исключений IEEE 754 по умолчанию, заключающееся в возобновлении после предварительной подстановки значения по умолчанию, позволяет избежать рисков, присущих изменению потока управления программой при числовых исключениях. Например, запуск космического корабля Cluster в 1996 году закончился катастрофическим взрывом, отчасти из-за политики обработки исключений Ada , которая прерывала вычисления при арифметической ошибке. Уильям Кахан утверждает, что поведение обработки исключений IEEE 754 по умолчанию предотвратило бы это. [19]
Фреймворки веб-разработки front-end , такие как React и Vue , ввели механизмы обработки ошибок, при которых ошибки распространяются вверх по иерархии компонентов пользовательского интерфейса (UI) способом, аналогичным тому, как ошибки распространяются вверх по стеку вызовов при выполнении кода. [21] [22] Здесь механизм границы ошибок служит аналогом типичного механизма try-catch. Таким образом, компонент может гарантировать, что ошибки из его дочерних компонентов будут перехвачены и обработаны, а не распространены на родительские компоненты.
Например, в Vue компонент будет перехватывать ошибки, реализуяerrorCaptured
Vue.component ( 'parent' , { template : '<div> <slot> </slot></div>' , errorCaptured : ( err , vm , info ) => alert ( 'Произошла ошибка' ); }) Vue.component ( ' child' , { template : ' <div> { { cause_error()}}</div>' })
При таком использовании в разметке:
< родитель > < ребенок ></ ребенок > </ родитель >
Ошибка, создаваемая дочерним компонентом, перехватывается и обрабатывается родительским компонентом. [23]
ArrayIndexOutOfBoundsException
FileNotFoundException
FileNotFoundException
Возможно, наиболее распространенной формой метода обработки исключений, используемой программистами, является метод "кода возврата", который был популярен как часть C и UNIX.
{{cite journal}}
: Цитировать журнал требует |journal=
( помощь )