Отменить поведение спецификаций исключений в версии VC ++ 9.0
-
06-07-2019 - |
Вопрос
Я работаю над старым кодом, который в значительной степени зависит от поведения спецификаций исключений, описанных в языковом стандарте.А именно, вызовы std::unexpected() при нарушениях спецификации исключения в форме, описанной ниже.
foo() throw(T) { /*...*/ }
Спецификации Nothrow действительно гарантированно не выбрасываются, но бросок (T) ожидается, что они будут нарушены как по замыслу и...ну, потому что стандарт ожидает именно этого и предоставляет механизм для обработки этого.
Причины этого связаны с решением разработчиков использовать EH также в качестве механизма обработки ошибок (управляемого собственной иерархией классов ошибок) в дополнение к обработке исключений.Идиома, представленная в EH, точно соответствовала их потребностям, и они пошли по пути наименьших усилий.По крайней мере, так я это вижу, и это не особенно шокирует меня, учитывая размер и сложность системы.
Однако сейчас мне поручено включить новая и несвязанная функциональность и код ведет себя не так, как ожидалось в VC ++ 9.0, из-за отклонения от стандартов, касающихся спецификаций исключений, введенных в 8.0.(ссылка: Майкрософт)
Я пытаюсь найти способ навязать стандартное поведение.Надеялся, что компилятор предложит запасной вариант.Но такового нет.
Неужели мне не повезло и мне нужно изменить правильно написанный, послушный стандарту код, работающий на 350 000 строках кода с полностью разработанной иерархией классов обработки ошибок?Или вы можете придумать способ, который поможет мне принудительно использовать std::unexpected()?
Редактировать: Я предоставляю некоторую справочную информацию.Рассматриваемая система представляет собой генератор календарей учебного года для школы, в которой обучается чуть более 4000 учащихся, распределенных между, я пока не уверен в некоторых цифрах, 6 классами и ~ 190 классами, плюс 12 виртуальных (дистанционное обучение) классов.О MINGW не может быть и речи, как и о любом другом компиляторе, отличном от VC ++ 8.0 или 9.0.Это связано с правилами, касающимися программного обеспечения, обслуживающего Систему образования в этой стране.
Изменения, необходимые в коде, предназначены именно для того, чтобы приспособиться к внедрению виртуальных классов с совершенно иной схемой генерации календаря.И тут я столкнулся с этой проблемой.Программное обеспечение активно использует механизм исключений в нескольких частях процесса генерации календаря как средство управления рабочим процессом с помощью как неожиданных () сопоставлений (сохраненных и восстановленных), так и сопоставлений bad_exception, ни одно из которых не работает в VC ++.С чисто личной точки зрения, я нахожу существующий механизм действительно очень элегантным, хотя и совершенно необычным.Но я отвлекся.
Решение
Как вы упомянули, в Visual Studio есть "интересный" способ работы со спецификациями исключений:
throw()
имеет свое обычное значение (функция не должна выдавать)- все остальное (включая отсутствие спецификации исключения) интерпретируется как
throw(...)
Нет никакого способа обойти это.Однако сообщество C ++ в значительной степени согласно с тем, что спецификации исключений бесполезны.Вам действительно нужна проверка типов ошибок во время выполнения?Возможно, правильное модульное тестирование может заменить ваши проверки во время выполнения.
Другие советы
Я не верю, что поведение спецификации исключений Visual C ++ когда-либо соответствовало (или утверждало, что соответствовало) стандартам - даже до версии 8.0, - поэтому я не уверен, как работало приложение.
Возможно ли выполнить такие изменения, как:
void f() throw(T)
{
// ...
}
Для:
void f()
{
try
{
// ...
}
catch (T)
{
throw;
}
catch (...)
{
app_unexpected();
}
}