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

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

Ответы на вопрос(5)

Это сложная деталь реализации, но в 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, они почти всегда противны.

 Alexandru19 мар. 2014 г., 04:05
Также важно отметить, что _set_se_translator () вызывается только один раз для каждого вызова функции в стеке, который имеет блоки try, в соответствии с MSDN, и должен быть установлен для каждого потока.
 Alexandru19 мар. 2014 г., 04:04
Будут ли __try / __ кроме блоков перехватывать все исключения SEH, а также все исключения C ++?

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

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

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

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

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

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

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

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

Решение Вопроса

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

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

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

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

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

 Krishnan27 сент. 2010 г., 13:40
Спасибо всем, кто внес свой вклад. :)
 mcdave24 сент. 2010 г., 16:56
Его интересный @peterchen видел работу MFC с компилятором без VC. MFC, когда все это сводится к нулю, представляет собой набор классов и макросов, которые основаны на Win32 C API, поэтому он должен был быть скомпилирован компиляторами без VC, но я сомневаюсь, что это было задумано. Кроме того: если вы углубитесь в исходный код MFC, вы сможете многое узнать о том, как обернуть цикл сообщений Windows для удовлетворения пользовательских потребностей.
 peterchen24 сент. 2010 г., 16:33
@ Ганс, правда? / EHa против / EHs влияет только на то, перехватывает ли обработчик исключений C ++ структурированные исключения. Я уверен, что стандарт C ++гарантии очистка для исключений C ++ (оставлять эту реализацию определенной не имеет смысла, так как необходимый код будет принципиально другим).
 peterchen24 сент. 2010 г., 16:28
MFC действительно работал на Watcom C / C ++ 10. Как-то. Без волшебников и прочего.
 Matteo Italia24 сент. 2010 г., 15:49
Ради любопытства, MFC когда-либо предназначались для работы на любом компиляторе, кроме VC ++?
 peterchen27 сент. 2010 г., 18:43
@TheUndeadFish: Спасибо за обновление, я все еще хочу держать его в списке, потому что это третий набор синтаксиса и правил, как обрабатывать исключения.
 peterchen24 сент. 2010 г., 20:44
@mcdave: я, наверное, показываю свой возраст :)
 Hans Passant24 сент. 2010 г., 16:27
Исключения C ++ не требуются для гарантии очистки. Компилировать с / EHa.
 TheUndeadFish24 сент. 2010 г., 19:40
В то время как исключения MFC использовались в прошлом разными методами (я думаю, что раньше VC поддерживал исключения C ++), исключения MFC теперь строятся поверх исключений C ++. На самом деле вполне возможно преобразовать макросы MFC в C ++ try / catch, как описано здесь:msdn.microsoft.com/en-us/library/19z28s5c.aspx Итак, под всем этим на самом деле есть только 2 разных типа: исключения C ++ и SEH.

Ваш ответ на вопрос