Разница между исключением C ++ и структурированным исключением - PullRequest
20 голосов
/ 24 сентября 2010

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

Ответы [ 5 ]

21 голосов
/ 24 сентября 2010

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

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

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

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

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

10 голосов
/ 24 сентября 2010

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

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

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

7 голосов
/ 24 сентября 2010

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

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

5 голосов
/ 24 сентября 2010

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

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

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

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

1 голос
/ 24 сентября 2010

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

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

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