Что лучше использовать, __try / __ кроме блока или блока try / catch? - PullRequest
26 голосов
/ 17 сентября 2010

Мне интересно, какой лучший способ отловить исключения, которые я выбрасываю: блок __try / __except или блок try / catch?

Я пишу на C ++, и программа будет использоваться только на Windows, поэтому переносимость не является проблемой.

Спасибо!

Ответы [ 5 ]

44 голосов
/ 17 сентября 2010

Это две очень разные вещи.try / catch - это знакомые вам ключевые слова C ++.__try/__except используется для отлова исключений SEH.Исключения, возникающие в самой Windows, такие как DivisionByZero или AccessViolation.Это хорошо описано в статье библиотеки MSDN .

Вы также можете использовать ее для перехвата исключения C ++, поскольку он использует функцию Windows SEH.Однако вы не можете извлечь из него брошенный объект исключения, поэтому будет нулевой контекст, если вы действительно хотите обработать исключение.Что безумие.Подход номер один - никогда не ловить исключения SEH, они всегда брутто.Если вам нужно объединить их, используйте _set_se_translator (), чтобы преобразовать исключение SEH в исключение C ++.

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

Вы должны использовать блок try / catch.

Как уже отвечали другие, __try / __except предназначен для отлова SEH (ошибки, генерируемые окнами), а не для отлова общих исключений.

Самое главное, __try и __catch могут не запускать деструкторы C ++ или корректно раскручивать стек при возникновении исключения.

За исключением редких случаев, вы никогда не должны пытаться перехватить SEHисключения.

РЕДАКТИРОВАТЬ: Ну, я был уверен в этом (это то, что мне всегда говорили), но @Hans говорит, что, очевидно, есть переключатель компилятора, который вы можете использовать для измененияэтот.Я думаю, что документы по /EHa вводят в заблуждение или, по крайней мере, не полностью, о том, что здесь происходит.Если кто-то найдет окончательные документы, доказывающие, что это неверно, я с радостью удалю этот ответ.

Даже если окажется, что это неверно, вы все равно должны использовать try и catch просто потому, что они стандартные,в то время как __try и __except нет.

6 голосов
/ 17 сентября 2010

__try/__except предназначен для вызова кода Win32 C, который не поддерживает исключения, но использует структурированный код ошибки / механизм обработки. __try/__except переведет ошибки C в блок исключений , аналогичный для C ++ try / catch.

Дополнительные сведения см. В этой статье MSDN .

.
4 голосов
/ 17 сентября 2010

Стандартный C ++ использует блоки try / catch, поэтому я рекомендовал бы использовать их, если вам нужен «стандартный» механизм исключений, основанный на стандартной библиотеке C ++.

Однако, если вы планируете использовать Структурную обработку исключенийпредоставляется через Windows SDK (см. здесь ), затем используйте __try / __except.

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

После того, как вы что-то бросили, у вас больше нет выбора, как его поймать. Если вы генерируете исключения C ++ (то есть с throw), тогда используйте try / catch. Если вы выбрасываете исключения Windows (то есть, с RaiseException), тогда используйте __try / __except. Попытка смешать их просто добавит ненужных хлопот в вашу жизнь.

...