Требуется ли для обработки исключений объектно-ориентированное программирование? - PullRequest
40 голосов
/ 20 декабря 2011

На этом этапе своего опыта программирования я понимаю, насколько я испорчен тем, что обработка исключений доступна в большинстве языков, используемых сегодня (C ++, .Net, Java и т. Д.), По крайней мере по сравнению с C. Я готовлюсь чтобы пройти продвинутый курс C и я действительно думаю об этих терминах по сравнению с моей нынешней парадигмой.

В C программист в первую очередь должен предотвратить возникновение ошибок, что весьма пугает любого, кто привык к обработке исключений. Мне пришло в голову, что любой язык, с которым я сталкиваюсь и который обрабатывает исключения, оказывается объектно-ориентированным. Первым объектно-ориентированным языком для обработки исключений, по крайней мере, насколько мне известно, является C ++, который является своего рода развитием языка C. (пожалуйста, исправьте меня, если я ошибаюсь)

С учетом сказанного, есть ли что-то в объектно-ориентированной природе языка, которая допускает обработку исключений, или была добавлена ​​обработка исключений в качестве функции, поскольку объектно-ориентированные языки действительно стали обычным явлением? Чего не хватает С, чтобы сказать, С ++, в машинном коде, который заставляет работать исключения?

Я нашел этот пост о том, как обработка исключений работает под капотом, но не уверен, как эта информация применима к моему вопросу ( т. Е. Не хватает ли C уведомлений, продолжений и т. Д.? ). Заранее спасибо.

Ответы [ 9 ]

20 голосов
/ 20 декабря 2011

C ничего не лишено в машинном коде, и обработка исключений была и является обычным явлением в C с setjmp и longjmp.

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

15 голосов
/ 20 декабря 2011

Требуется ли для обработки исключений объектно-ориентированное программирование?

Нет.Два совершенно разные.Можно иметь языки OO, которые не имеют обработки исключений в качестве примитива потока управления, и можно иметь обработку исключений в языках не OO.

Объектно-ориентированное программирование, как подсказывает Википедия, - это стиль программирования, в котором подчеркивается значение , инкапсуляция , обмен сообщениями , модульность , полиморфизм и наследование для достижения недорогого повторного использования кода и эффективного управления сложными программными проектами, реализуемыми большими группами.

В этом списке вы не видите «циклы», «операторы if», «goto» или «try-catch-finally-throw», потому что примитивы потока управления не имеют ничего общего сабстракция, инкапсуляция, обмен сообщениями, модульность, полиморфизм или наследование, используемые для достижения повторного использования недорогого кода или эффективного управления сложными программными проектами большими группами.

Чему не хватает C, чтобы сказать, C ++, в машинном коде, который заставляет работать исключения?

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

Но, тем не менее, ничто не мешает вам или кому-либо еще разрабатывать новую версию C, в которой обработка исключений является примитивом потока управления, но без всех других функций C ++.

Если вам интересен вопрос о том, как добавить обработку исключений к не-OO-языкам, поддерживающим продолжения, см. Мою статью на эту тему, которая очерчивает идею:

http://blogs.msdn.com/b/ericlippert/archive/2010/10/22/continuation-passing-style-revisited-part-two-handwaving-about-control-flow.aspx

10 голосов
/ 20 декабря 2011

С учетом сказанного, есть ли что-то в объектно-ориентированной природе языка, которая допускает обработку исключений, или добавлена ​​обработка исключений в качестве функции, поскольку объектно-ориентированные языки действительно стали обычным явлением?

Впервые я узнал об исключениях, когда мне пришлось изучать Аду (изучение CS) в начале 90-х годов.IIRC, у Ады был особый тип Exception.Тогда это был не объектно-ориентированный язык.(Ada95 добавил некоторые концепции ОО.) Однако я согласен с тем, что раскрутка стека (т.е. полная автоматическая очистка выделенных ресурсов) является важной особенностью успеха обработки исключений.Объединение деструкторов с обработкой исключений является важным моментом для успеха исключений в C ++.

Кажется, я также помню, как Страуструп упоминал, что Ada оказывает большое влияние на обработку исключений в C ++.

7 голосов
/ 20 декабря 2011

Требуется ли для обработки исключений объектно-ориентированное программирование?

Нет.Два ортогональны.Другие упоминали setjmp и longjmp, используемые в C для обработки ошибок.Я хочу упомянуть SEH.

SEH (структурированная обработка исключений) - расширение Microsoft для C с поддержкой на уровне ОС.Это позволяет вам писать код, например ( пример из MSDN ):

__try 
{ 
    *pResult = dividend / divisor; 
} 
__except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO ? 
         EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{ 
    // handle exception
}

Вы также можете вызывать свои собственные исключения, вызывая RaiseException.В отличие от setjmp и longjmp вы можете выполнять свою собственную очистку в __finally блоках.Фактически исключения C ++ реализованы поверх SEH (в окнах).

Это пример обработки исключений полностью неориентированным способом.

Еще один пример в C ++, который неиспользовать любые объектно-ориентированные функции:

try {
    throw "Boom!";
} catch(const char* str) {
    printf("Error: %s\n", str);
}
5 голосов
/ 20 декабря 2011

Необъектно-ориентированные языки, которые реализуют обработку исключений, включают:

  • ITS TECO
  • PL / 1 (Multics)
  • C (как это делают несколько человек)указал через setjmp / longjmp)
  • C посредством сигналов Unix: сигналы ядра Unix получены из средства обработки исключений Multics
  • более старые версии Lisp (предоставлено,Common Lisp разрешает ООП, но не делает, когда добавляются условия и перезапуски), которые, по-видимому, реализуют условия и перезапускают (unwind-protect s) из ITS TECO - согласно RMS (http://www.gsim.aoyama.ac.jp/~ida/GNU/RMStalk1207.html),, подразумевая, что Lisp фактически унаследовал обработку исключений посредствомEmacs (отличный!)
4 голосов
/ 21 декабря 2011

В качестве необязательного примера попробуйте Haskell для размера.Исключения даже не нужно встраивать в язык;они просто являются частью возвращаемого типа (например, Either MyException MyValue или ExceptionalT IOException IO String).Стандартные исключения могут быть обработаны с помощью функции try из модуля Control.Exception:

main = do
  result <- try (evaluate (1 `div` 0))
  case result of
    Left  exception -> putStrLn $ "Caught: " ++ show exception
    Right value     -> putStrLn $ "Result: " ++ show value

Вы также можете использовать функцию в качестве обработчика исключений с функцией catch, здесь используется инфикс:

main = (print $ 1 `div` 0) `catch` \exception ->
  putStrLn $ "Caught: " ++ show exception

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

main =
   do result <- runExceptionalT someFunction
      case result of
         Exception exception -> putStrLn ("Caught: " ++ show exception)
         Success   value     -> putStrLn ("Result: " ++ show value)

Поскольку исключение является частью сигнатуры типа функции, оно должно быть явно учтено.По сути, это то же самое, что проверенные исключения в Java.

1 голос
/ 20 декабря 2011

Не-OO языки также имеют исключения, это полезная абстракция для раскрутки стека вызовов. Примерами являются Erlang и Forth .

1 голос
/ 20 декабря 2011

Обработка исключений существует довольно давно, задолго до C ++. Несколько «бутиковых» языков реализовали обработку исключений довольно рано, но Ada (конец 70-х, IIRC) была, вероятно, самой известной. У Ады были проблески ОО-сущности, но она не была ОО по каким-либо современным стандартам.

Обработка исключений была также реализована в нескольких версиях языков PL / S (определенно не OO), которые в основном использовались внутри IBM. Ранние реализации (начиная с конца 70-х годов) были разработаны с использованием макросов (макропроцессор PS / S превосходил большинство с тех пор), но более поздние версии встраивали EH в язык.

1 голос
/ 20 декабря 2011

Что ж, исключения встречаются на ассемблере, где вы можете использовать ловушки (принудительное исключение) и другие исключения для управления потоком программы.Примером может быть нулевой указатель или почему не переполнение стека.В природе ОО-языков нет ничего, что позволяло бы обрабатывать исключения.Они просто делают это проще (а языки высокого уровня имеют тенденцию генерировать намного больше исключений).Исключения - ключевая особенность в базовом программировании.И под этим я не подразумеваю все программирование, я имею в виду «обычное» программирование, включая сборку.Я не понимаю, что вы имеете в виду, когда говорите «что в C не хватает того, что сказать, C ++, в машинном коде, который заставляет работать исключения?».И я бы не сказал, что программист должен перехватывать исключения в C (но я новичок в этой области. Если кто-то может исправить меня, пожалуйста, сделайте).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...