Каковы последствия смешивания моделей обработки исключений в Visual Studio 2010? - PullRequest
7 голосов
/ 29 июня 2011

У меня есть сторонняя статическая библиотека, построенная с Enable C++ Exceptions, установленным на Нет (флаг /EH не указан).Каковы последствия обращения к нему из кода, созданного с включенными исключениями C ++ (/EHa)?Если из библиотеки выдается структурное исключение, будет ли надежно вызываться функция, предоставляемая _set_se_translator основным приложением?(Мои эксперименты показывают, что так и будет, но просто интересно, определено ли это поведение).

Существуют ли другие соображения при смешивании /EH моделей обработки исключений?

Ответы [ 2 ]

5 голосов
/ 10 декабря 2011

Согласно MSDN , можно смешивать / EHa и / EHsc :

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

Но, похоже, есть исключение из этого правила, то есть при передаче исключений из неуправляемого (/ EHsc) в managed (/ clr) . Управляемые коды перехватывают все исключения, используя структурированную обработку исключений (SEH), и это приводит к тому, что неуправляемые деструкторы не будут вызываться при разматывании стека. Есть разные обходные пути:

  1. Измените неуправляемый код, чтобы использовать / EHa вместо / EHsc. Это имеет недостаток в том, что catch (...) в неуправляемом коде внезапно обнаружит нарушения прав доступа и другие сумасшедшие вещи.
  2. Создать блок try-catch в неуправляемом коде и убедиться, что между неуправляемым миром и управляемым миром не передаются никакие исключения.

    2,1. Возможный промежуточный путь состоит в том, чтобы гарантировать, что никакие деструкторы не будут вызываться при передаче исключения из неуправляемого в управляемый мир. В неуправляемом коде создайте оболочку try-catch, а затем в блоке catch перебросьте исключение в управляемый мир.

5 голосов
/ 29 июня 2011

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

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

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

...