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