В вычислительной технике и компьютерном программировании обработка исключений — это процесс реагирования на возникновение исключений — аномальных или исключительных условий , требующих специальной обработки — во время выполнения программы . Как правило, исключение нарушает нормальный поток выполнения и запускает заранее зарегистрированный обработчик исключений ; Подробности того, как это делается, зависят от того, является ли это аппаратным или программным исключением, а также от того, как это программное исключение реализовано.
Исключения определяются различными уровнями компьютерной системы, и типичными уровнями являются прерывания , определяемые процессором , сигналы , определяемые операционной системой (ОС) , исключения, определяемые языком программирования . Каждый уровень требует разных способов обработки исключений, хотя они могут быть взаимосвязаны, например, прерывание ЦП может быть преобразовано в сигнал ОС. Некоторые исключения, особенно аппаратные, могут обрабатываться настолько изящно, что выполнение может возобновиться там, где оно было прервано.
Определение исключения основано на наблюдении, что каждая процедура имеет предварительное условие , набор обстоятельств, при которых она завершается «нормально». [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]
Фреймворки интерфейсной веб-разработки , такие как React и Vue , ввели механизмы обработки ошибок, при которых ошибки распространяются вверх по иерархии компонентов пользовательского интерфейса (UI) аналогично тому, как ошибки распространяются вверх по стеку вызовов при выполнении кода. [21] [22] Здесь механизм границы ошибки служит аналогом типичного механизма try-catch. Таким образом, компонент может гарантировать, что ошибки его дочерних компонентов будут перехватываться и обрабатываться, а не распространяться на родительские компоненты.
Например, в Vue компонент будет обнаруживать ошибки, реализуяerrorCaptured
Вю . компонент ( 'parent' , { шаблон : '<div><slot></slot></div>' , errorCaptured : ( err , vm , info ) => alert ( 'Произошла ошибка' ); }) Vue . компонент ( 'дочерний' , { шаблон : '<div>{{ Cause_error() }}</div>' })
При таком использовании в разметке:
< родительский > < дочерний >/ дочерний > </ родительский >
Ошибка, вызванная дочерним компонентом, перехватывается и обрабатывается родительским компонентом. [23]
ArrayIndexOutOfBoundsException
FileNotFoundException
FileNotFoundException
Вероятно, наиболее распространенной формой метода обработки исключений, используемой программистами, является метод «кода возврата», который был популяризирован как часть C и UNIX.
{{cite journal}}
: Требуется цитировать журнал |journal=
( помощь )