Неуправляемый код Visual C++: использовать исключения /EHa или /EHsc для C++?

Если я создаю новый проект в неуправляемом C++, Visual Studio 2008 или более поздней версии, какую модель обработки исключений я хочу использовать?

Я понимаю, что опция /EHa приводит к снижению эффективности кода, а также перехватывает исключения SEH, верно?

Поэтому я избегал этой опции и обычно использовал /EHsc, так что я перехватываю только исключения C++, которые на самом деле выбрасываются, а не перехватывает нарушения доступа и другие структурированные исключения в обработчиках catch(...). Если в моем коде есть нарушение прав доступа, я не хочу, чтобы он был замаскирован с помощью catch(...) {}.

Я пишу код другим, которые хотят, чтобы catch(...) {} ничего не делала, и они даже хотят, чтобы это делалось, если есть нарушение прав доступа, что для меня кажется очень плохой идеей. Если есть ошибка из-за плохого кодирования, вы не хотите засунуть пальцы в уши и громко сказать: "La la la la la!" чтобы у вас не было сбоев программы? На самом деле, если код сейчас находится в плохом состоянии из-за ошибки кодирования, действительно ли вы хотите, чтобы код продолжался?

Таким образом, моя общая мысль заключается в том, что /EHa создает больший / более медленный код и позволяет программистам сойти с рук при написании кода, который, если присутствует фатальная ошибка, будет продолжать работать в неопределенном состоянии.

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

Пожалуйста, взвешивайте свои мысли.

2 ответа

Решение

/ ЭХА делает две вещи. Прежде всего, он подавляет оптимизацию, которая исключает фильтры исключений, которые автоматически вызывают деструкторы локальных переменных класса, если анализатор кода не может увидеть код, который может вызвать исключение C++. Это делает разматывание стека безопасным для любого вида исключения, а не только для исключения C++. Затраты на эти фильтры исключений составляют время на x86 и пространство на x86 и x64.

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

Реально, вам нужно перейти на использование __try/__except так что вы можете написать свой собственный фильтр исключений и избежать выявления плохих. Код исключения для исключений C++ - 0xe04d5343 ("MSC"). Использование _set_se_translator() было бы другим подходом.

Я использую / EHa, потому что это безопасно для взаимодействия.NET, тогда как / EHsc может не быть; см. Деструкторы, не вызываемые, когда собственное (C++) исключение распространяется, например, на компонент CLR.

Однако, если для определенного фрагмента кода действительно важна дополнительная производительность и вам не нужна совместимость с.NET (или чем-то еще), то, конечно, / EHsc звучит нормально.

Ни / EHsc, ни / EHa не отлавливают большинство ошибок памяти, поэтому их использование для выявления нарушений доступа является безнадежным случаем.

Другие вопросы по тегам