Является ли VERIFY (...) хорошей практикой в ​​кодировании C ++? - PullRequest
10 голосов
/ 15 апреля 2010

Кроме того, как это можно сравнить с выдачей исключения, когда что-то идет не так?

Ответы [ 3 ]

19 голосов
/ 15 апреля 2010

VERIFY() служит для той же цели, что и ASSERT() (или стандартная библиотека assert()) - чтобы вы могли уловить вещи, которые на самом деле никогда не должны происходить ™ (т. Е. Настоящая ошибка кода) , то, что должно быть исправлено перед выпуском). Такие вещи, которые, если по какой-то причине выражение ложное, нет смысла продолжать, потому что что-то ужасно, ужасно неправильно.

Это отражается в том факте, что VERIFY() останавливает программу только при ложной оценке при компиляции в режиме отладки - в режиме Release она прозрачна. Разница между VERIFY() и ASSERT() заключается в том, что VERIFY() будет по-прежнему оценивать выражение в режиме Release, его просто не волнует результат - тогда как ASSERT() полностью удаляется из программы при компиляции в режиме Release и таким образом, никаких побочных эффектов выражения внутри него не будет.

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

6 голосов
/ 15 апреля 2010

Вопрос выглядит простым, но скрывает огромную тему: устранение ошибок.

Подводя итог, я бы сказал, assert и verify - это инструменты, используемые в процессе разработки , в то время как исключения и проверка системных вызовов являются нормальными части производственного кода для устранения ошибок времени выполнения .

  • Утверждения (применяется для подтверждения и проверки) - это инструменты, которые в основном используются в стиле защитного программирования. Их главная цель - защитить от случаев, которые никогда не должны происходить, и программист не знает, что делать, если это произойдет. Обычно он используется для проверки ошибок программирования. Когда во время отладки программы происходит невозможное, вы обычно хотите обнаружить ее и сообщить о ней как можно быстрее. Это упростит исправление ошибок. Вы можете использовать его с некоторым условием или даже как assert(false), как правило, чтобы проверить, что ветвь коммутатора никогда не перехватывается.

    Я в основном использую утверждения при работе со сторонним кодом, поведение которого я не уверен. Для проверки поведения моего собственного кода в процессе разработки я обычно предпочитаю модульное тестирование.

    Теперь, как учил нас Шрёдингер, события меняют вещи. Когда-нибудь у вас может появиться код, который работает в режиме отладки, когда включен assert, и перестает работать в режиме выпуска. Обычно это является признаком скрытой ошибки в условии утверждения (побочный эффект, чувствительный ко времени код). Убедитесь, что минимизируете этот вид риска, но это может считаться плохой практикой, например, подметание пыли за ковром.

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

  • Исключения являются нормальной частью процесса управления программой. Чаще всего они используются для устранения ошибок, но это не единственное их возможное использование (те, кто использует другие языки, такие как python, поймут, о чем я говорю). Они также не должны рассматриваться как единственный инструмент управления ошибками. Если системные библиотеки не поддерживают C ++, системные вызовы по-прежнему возвращают код ошибки, а не вызывают исключение.

    Как правило, исключения должны перехватываться ближайшим объектом, который способен их разумно обрабатывать.

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

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

5 голосов
/ 15 апреля 2010

В Visual C ++ есть два макроса для проверки условий: ASSERT и VERIFY.

В режиме отладки они оба ведут себя одинаково: то есть они оба оценивают свои аргументы и, если результат равен 0, они оба останавливают программу с помощью диалогового окна сбоя подтверждения.

Разница заключается в режиме выпуска. В режиме release режим ASSERT полностью удален из программы: он вообще не оценивает его выражение. VERIFY, с другой стороны, все еще оценивает выражение, просто игнорирует результат.

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

...