Я обычно добавляю множество утверждений в свой код на C ++, чтобы упростить отладку, не влияя на производительность сборок выпуска. Теперь assertэто чистый C макро разработан без механизмов C ++ в виду.
C ++, с другой стороны, определяет std::logic_error, что должно быть выброшено в случаях, когда есть ошибка в логике программы (отсюда и название). Создание экземпляра может быть просто идеальной альтернативой в стиле C ++ assert.
Проблема заключается в том, что assertи abortкак завершить программу сразу без вызова деструкторов, поэтому пропуск очистки, в то время как бросать исключение вручную добавляет ненужные затраты времени выполнения. Один из способов обойти это - создать собственный макрос утверждения SAFE_ASSERT, который работает так же, как аналог C, но выдает исключение при ошибке.
Я могу придумать три мнения по этой проблеме:
- Придерживайтесь утверждения С. Поскольку программа завершается немедленно, не имеет значения, правильно ли развернуты изменения. Кроме того, использование
#defines в C ++ так же плохо. - Бросить исключение и поймать его в main () . Разрешение коду пропускать деструкторы в любом состоянии программы является плохой практикой, и ее следует избегать любой ценой, как и вызовов terminate (). Если выбрасываются исключения, их нужно перехватывать.
- Вызвать исключение и позволить ему завершить программу. Исключение, завершающее программу, - это нормально, и поэтому
NDEBUGэтого никогда не произойдет в сборке выпуска. В захвате нет необходимости, и он раскрывает детали реализации внутреннего кодаmain().
Есть ли однозначный ответ на эту проблему? Любая профессиональная рекомендация?
Отредактировано: пропуск деструкторов, конечно, не является неопределенным поведением.
logic_errorэто логическая ошибка. Ошибка в логике программы называется ошибкой. Вы не решаете ошибки, выбрасывая исключения.