Intereting Posts
оцениваются операнды sizeof? Как получить доступ к перечислению C ++ из QML? Построение временного вызова функции интерпретируется как декларация Динамическое меню с использованием mfc как инициализировать Eigen Matrix из opencv cv :: Mat или из массива, который является строковым? Является ли указатель на переменную таким же, как указатель на массив одного элемента или нулевые элементы? C ++ Множественное определение основного Вызов функции базового classа C ++ из последнего полученного в дизайне алмаза Использование read () непосредственно в C ++ std: vector Каков современный эквивалентный (C ++) стиль для более старого (C-like) метода fscanf? Cmake и QT5 – Включить только один аргумент Как хранить более 2 переменных в unordered_map? C ++ Tuple vs Struct Когда я должен использовать новый диапазон и могу ли я объединить его с новым cbegin / cend? Указатель C ++ и ссылка с новым ключевым словом при создании экземпляра

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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