Страницы

Поиск по вопросам

пятница, 14 февраля 2020 г.

Зачем нужен флаг /EHsc для MSVC компилятора?

#cpp #visual_cpp #исключения


Зачем нужен флаг /EHsc для MSVC компилятора? Недавно увидел его в конфиге, почитал
доки, но так и не понял о каких синхронных/асинхронных исключениях идёт речь. Это расширение
компилятора или всё соответствует стандарту C++?
    


Ответы

Ответ 1



Примерно (не в точных деталях, просто для примерного понимания) так - если использовать /EHa, то это и есть расширение VC++, которое всякие неприятности типа деления на ноль и т.п. трансформирует в исключения С++ и перехватывает их как исключения. /EHs - это перехват только стандартных исключений, ну а добавление c - считать, что функции, объявленные как extern "C", исключений не генерируют. Попробуйте скомпилировать что-то вроде int main(int argc, const char * argv[]) { try { int x = 5; int y = 0; x /= y; cout << " x = " << x << endl; } catch(...) { cout << "Exception!\n"; } } с тем и другим ключом и посмотреть на результат выполнения. Мое личное отношение к /EHa - не люблю нестандартные расширения компиляторов в принципе. Тем более сами MS пишут - Specifying /EHa and trying to handle all exceptions by using catch(...) can be dangerous. In most cases, asynchronous exceptions are unrecoverable and should be considered fatal. Catching them and proceeding can cause process corruption and lead to bugs that are hard to find and fix. Еще раз - это не более чем краткое (a la научпоп :)) описание, не претендующее на точность и тем более на полноту.

Ответ 2



В Windows существует механизм структурированных исключений, Structured Exception Handling (SEH). Этот механизм используется при обработке различных исключительных ситуаций, таких как деление на 0 или ошибка доступа. Компилятор VC++ (и другие) реализует исключения C++ поверх этого механизма. То бишь он присутствует всегда, однако это детали реализации. Исключения SEH там называются асинхронными исключениями, а исключения С++ синхронными. Так вот, опция /EH задает, как компилятору работать с этими двумя видами исключений. Она принимает один или более модификаторов: a - перехват синхронных и асинхронных исключений в C++ блоке try{}catch(...){} - это нестандартное поведение s - перехват только синхронных исключений в C++ блоке try{}catch(...){} - такое поведение соответствует стандарту с (используется совместно с s) - это директива оптимизации, указывающая компилятору предположить, что "C" функции никогда не кидают синхронных исключений r - это директива анти-оптимизации, запрещающая компилятору устранять избыточные проверки при работе с функциями, помеченными noexcept (то бишь предположить, что они все равно могут выкинуть исключение) Еще компилятор поддерживает нестандартный синтаксис __try{}__except{} и __try{}__finnaly{} для работы с SEH исключениями, однако это от опции /EH не зависит.

Комментариев нет:

Отправить комментарий