Когда следует использовать assert ()?


При разработке большого проекта программирования на C++ со многими разработчиками мы столкнулись с проблемами, связанными с неправильным использованием assert() в коде, что приводит к плохому качеству, когда утверждение действительно происходит, и продукт аварийно завершает работу.

Вопрос в том, какие хорошие принципы следует применять для надлежащего использования assert ()? Когда уместно использовать assert (), а когда нет? Существует ли перечень критериев, которым должно соответствовать каждое утверждение, чтобы быть легитимным? Как мы можем поощрять правильное использование assert ()?

В качестве первой трещины в этом, я бы сказал, что assert () должен использоваться только для документирования условия, которое считается невозможным достичь и которое должно быть идентифицировано как ошибка assert () во время выполнения, где она когда-либо возникнет из-за нарушения допущений программирования.

Могут ли люди сделать лучше, чем это? Каков ваш опыт работы с assert ()?

4 10

4 ответа:

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

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

Вы должны использовать assert для проверки всех условий, которые никогда не должны выполняться:

  • предварительные условия для входных параметров
  • результаты промежуточных расчетов
  • постусловия состояния объекта

Но вы должны включать эти утверждения только в отладочные сборки или при явной активации для выпуска (не в сборках, выпущенных для клиентов).

Я использую assert для проверки любую нежелательных государственной программы:

  • предпосылки функционирования
  • Иногда я вставляю их в макрос после каждого вызова API: glDrawArray(); checkOpenGLError();--checkOpenGLError () вызовет getGLError (), если он включен
  • целостность структуры данных: assert(something = = null);
  • Иногда GDB лжет мне (iOS SDK 3.2). Я использую утверждения, чтобы доказать это.

Правка:

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

В настоящее время большая часть кода имеет множество внешних зависимостей и связей. Я не склонен использовать традиционные утверждения в наши дни, я предпочитаю исключения. Я не чувствую, что могу предположить, что "этого никогда не произойдет", и проверки могут быть безопасно удалены в не отладочной сборке.