Знаете ли вы о каких-либо других подходах к обработке ошибок, кроме try/catch и его вариаций?


Мне интересно знать некоторые другие подходы к обработке ошибок в языках программирования, кроме try / catch и его вариаций.

Знает ли кто-нибудь интересные случаи такой обработки ошибок?

3 5

3 ответа:

Ну, есть еще старый добрый

ON ERROR RESUME NEXT

Кроме того, некоторые языки программирования (некоторые Лиспы и схемы, возможно, Smalltalk) отделяют Создание исключения от экранирование (т. е. разматывание стека). То есть, в некоторых обстоятельствах можно обработать исключение в контексте, где оно возникает, и продолжить вычисление-это называется непрерывными исключениями.

В целом, представляется, что стратегии обработки ошибок можно разделить на три категории:

  • ничего не делать (ON ERROR RESUME NEXT, как упоминал Райан)
  • укажите ошибку / сбой в коде возврата. В некоторых случаях это может быть дополнительный выходной параметр, например указатель на индикатор ошибки, который устанавливается в случае ошибки.
  • вызовите альтернативный поток управления. Это может быть экстремальным (вызов abort() для остановки программы в холодном состоянии), или принимать форму обработки исключений или нечто подобное.

Существует ряд реализаций и стилей альтернативных потоков управления. Один из них-сигналы POSIX, которые часто приводят к завершению программы по умолчанию. Visual Basic также имеет альтернативный объект потока управления в ON ERROR GOTO.

Perl объединяет альтернативные управляющие потоки и коды возврата с помощью die, что приводит к завершению программы, в подинтерпретаторах, таких что запуск die в блоке eval'd приводит к установке кода ошибки в код вызова.

Тогда, конечно, существует традиционная обработка исключений, наряду с вариациями, такими как перезапускаемые/возобновляемые исключения Common Lisp. Даже подход signal/abort() и ON ERROR GOTO можно считать примитивными системами обработки исключений. Таким образом, рассматривая исключения в широком смысле, большинство альтернативных систем обработки ошибок потока управления можно рассматривать как некоторую форму обработки исключений.

Фактическая реализация исключений открывает интересный набор пространств проектирования. Существует несколько способов реализации языка могут сделать это:

  1. установите флаг / аномальное возвращаемое значение и верните вызывающий объект. То, что Perl требует от вас сделать явно - die и проверить переменную ошибки $? - это ручная версия этого метода. Язык программирования, выполняющий это, использует метод обработки ошибок возвращаемого кода для реализации исключений и может предоставлять их через конструкцию try-catch; Vala является хорошим примером этого.
  2. размотайте стек (как если бы функции возвращено) в обработчик исключений и запустите его. Это можно сделать непосредственно, либо с помощью машинного оборудования виртуальной машины, либо путем проверки стека. Он также может быть смоделирован с помощью (2); при использовании для реализации исключений эти два подхода в значительной степени семантически эквивалентны.
  3. вызовите код обработки исключений в динамической области кода, вызывающего ошибку. Это то, что Common Lisp делает со своей конструкцией condition-case - обработчик ошибок запускается без разматывания стека, а затем указывает, следует ли ошибка должна быть обработана повторной попыткой или размоткой.
  4. используйтедвуствольное продолжение, проходящее . В обычном стиле передачи продолжения (CPS) вместо того, чтобы возвращать значение, функция вызывает другую функцию (называемую продолжением), которая предоставляется ее вызывающим объектом в качестве одного из аргументов с результатом для "продолжения" вычисления. В двухствольном CPS вызывающий предоставляет два продолжения: одно для нормальных результатов и одно для ошибок. Это может быть использовано для реализации семантика эквивалентна семантике (1) и (2), но это интересная альтернативная стратегия, которая может открыть возможность построить более интересную семантику.
Итак, вкратце: существует три основных подхода: игнорировать ошибку, коды возврата и различные средства, подобные исключениям. Но в пространстве исключительных объектов существует множество вариантов как для семантики или интерфейса, так и для реализации этих семантик.

Есть старый добрый return-value. GO фактически использует возвращаемые значения вместо исключений. Поскольку C не имеет механизма исключений, он также использует возвращаемые значения плюс глобальную переменную (errno).

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