Подтвердить что ты не робот

Разница между исключением С++ и структурированным исключением

Может кто-нибудь объяснить разницу между исключением С++ и структурированным исключением в MFC?

4b9b3361

Ответ 1

На самом деле у вас есть три механизма:

  • Исключения С++, реализованные компилятором (try/catch)
  • Управление структурированными исключениями (SEH), предоставляемое Windows (__try/__except)
  • Макросы исключения MFC (try, catch - построены поверх исключений SEH/С++ - см. также комментарий TheUndeadFish)

Исключения в С++ обычно гарантируют автоматическую очистку во время разматывания стека (т.е. деструкторы локальных объектов), другие механизмы этого не делают.

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

MFC представила макросы исключения для поддержки исключений, даже если компиляторы не реализовали их.

Ответ 2

Это сложная деталь реализации, но в Windows исключение С++ также является исключением SEH. Код исключения - 0xE04D5343 (последние три байта = "MSC" ). И вся регулярная поддержка SEH используется для размотки стека, получения автоматического кода очистки для запуска и фильтрации исключения, поэтому выбрано правильное предложение catch. Получение объекта исключенного исключения в выражении фильтра - это сантехника, добавленная CRT за пределы того, что предоставляет SEH. SEH также поддерживает предложение __finally, но не используется в стандартном С++.

Еще одной деталью реализации является настройка компилятора /EH. Значение по умолчанию (/EHsc) позволяет компилятору оптимизировать созданный код и подавлять фильтры исключений, необходимые для автоматической очистки. Если он видит, что ни один из испущенных С++-кода не может вызвать исключение. Это прежде всего оптимизация пространства, небольшая оптимизация времени для кода x86, но не для кода x64. Чтобы получить автоматическую очистку для исключений SEH, вы должны скомпилировать с /EHa, чтобы эта оптимизация была подавлена.

Хорошей стратегией женитьбы на исключениях С++ с SEH является использование _set_se_translator(), поэтому вы можете перевести исключение SEH в исключение С++. Несмотря на то, что нередко разумно перехватывать исключения SEH, они почти всегда неприятны.

Ответ 3

Исключение С++ - это особенность языка программирования С++. Структурированное исключение - это другая концепция операционной системы Windows. Эти два используют аналогичный синтаксис, но технически разные. Структурированные исключения Windows не только используются с С++, но также, например, с C.

Иногда решение унифицировать обработку обоих: В приложении Windows вы можете предоставить функцию обработчика, которая захватывает все структурированные исключения и выдает исключение С++ (определенное вами).

Ответ 4

Оба обеспечивают механизмы разворачивания стека при возникновении ошибок.

Структурированные исключения предоставляются Windows при поддержке ядра. Они создаются Windows, если вы делаете что-то вроде доступа к недопустимому местоположению памяти. Они также используются для поддержки таких функций, как автоматический рост стека. Они используются довольно редко сами по себе, но языковые исключения на языках С++,.NET и подобных языках часто строятся поверх них. Для устранения этих исключений используются специальные ключевые слова, такие как __try и __catch. Однако иметь дело с ними сравнительно сложно и подвержено ошибкам, поскольку вы можете разбить такие функции, как автоматическое расширение стека, а также потенциально нарушать исключения языка С++.

Исключения С++ задаются языком С++. Типы данных, которые выбрасываются и захватываются, являются объектами С++ (включая возможность примитивных типов). Компилятор и среда выполнения реализуют их поверх основного структурированного механизма исключения. Это вы получите, если используете ключевые слова try, catch и throw языка С++.

Исключения SEH имеют больше возможностей, чем исключения С++, такие как поддержка возобновления и так называемые "векторизованные" обработчики (которые получают уведомления об исключениях, но не обязательно предотвращают разворот стека), но если вы специально не знаете, что хотите использовать их, я бы избегал их. Вероятно, наиболее частое использование их состоит в том, чтобы написать аварийный дамп, используя MiniDumpWriteDump, если ваша программа делает что-то незаконное или undefined.

Ответ 5

Исключения С++ будут работать с перекрестной платформой. К сожалению, SEH сильно ограничивает переносимость (за исключением случаев, когда они могут быть в разных версиях Windows).

Также SEH, похоже, захватывает множество собственных исключений Windows (например, Access Violation, Invalid handle был указан) и т.д.