Когда утверждения должны оставаться в рабочем коде? - PullRequest
147 голосов
/ 20 августа 2008

Обсуждение продолжается на comp.lang.c ++. Модерируется вопрос о том, следует ли сохранять в рабочем коде утверждения, которые по умолчанию существуют только в C ++ в отладочных сборках.

Очевидно, что каждый проект уникален, поэтому мой вопрос здесь не столько нужно ли сохранять утверждений , но в каких случаях это рекомендуется / не очень хорошая идея.

Под утверждением я подразумеваю:

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

Я не обязательно говорю о C или C ++.

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

Каково ваше мнение / опыт?

Приветствия

Карл

См. Связанный вопрос здесь


Отзывы и обновления

Привет, Грэм,

Утверждение является ошибкой, чисто и просто и поэтому должно рассматриваться как единое целое. Так как ошибка должна быть обработана в режиме релиза, вам не нужны утверждения.

Вот почему я предпочитаю слово «ошибка», когда говорю об утверждениях. Это делает вещи намного понятнее. Для меня слово «ошибка» слишком расплывчато. Отсутствующий файл - это ошибка, а не ошибка, и программа должна с ней справиться. Попытка разыменования нулевого указателя является ошибкой, и программа должна признать, что что-то пахнет плохим сыром.

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


Немного не по теме, но важный момент в обсуждении.

В качестве предупреждения, если ваши утверждения ломаются в отладчике, когда они терпят неудачу, почему бы и нет. Но существует множество причин, по которым файл не может существовать, которые полностью находятся вне контроля вашего кода: права на чтение / запись, переполнение диска, отключение USB-устройства и т. Д. Поскольку вы не можете контролировать его, я считаю, что утверждения не правильный способ справиться с этим.

Карл


Thomas

Да, у меня есть код завершения и должен сказать, что я категорически не согласен с этим конкретным советом.

Скажите, что ваш пользовательский распределитель памяти испортил и обнулел кусок памяти, который все еще используется другим объектом. Я получаю нулевой указатель, который регулярно разыменовывается в этом объекте, и один из инвариантов в том, что этот указатель никогда не равен нулю, и у вас есть пара утверждений, чтобы убедиться, что он остается таким. Что вы делаете, если указатель внезапно становится нулевым. Вы просто если () вокруг него, надеясь, что это работает?

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

Карл

Ответы [ 16 ]

1 голос
/ 25 декабря 2013

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

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

Однако, скажем, ваш fopen () задокументирован как всегда возвращающий действительный дескриптор открытого файла. Вы открываете файл и передаете его в функцию readfile ().

Эта функция readfile в этом контексте и, вероятно, в соответствии с ее спецификацией проекта, может в значительной степени предполагать, что получит правильный файл ptr. Поэтому было бы расточительно добавлять код обработки ошибок для отрицательного случая в такой простой программе. Тем не менее, он должен по крайней мере документировать предположение, каким-то образом - каким-то образом гарантировать - что это действительно так, прежде чем продолжать его выполнение. Он не должен на самом деле предполагать, что он всегда будет действительным, если он вызывается неправильно или копируется / вставляется в какую-либо другую программу, например.

Итак, readfile () {assert (fptr! = NULL); ..} уместно в этом случае, тогда как полноценная обработка ошибок - нет (игнорируя тот факт, что для чтения файла в любом случае потребуется некоторая система обработки ошибок).

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

1 голос
/ 27 октября 2012

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

0 голосов
/ 22 сентября 2013

ASSERTIONS не являются ошибками и не должны рассматриваться как ошибки. Когда выдается утверждение, это означает, что в вашем коде есть ошибка или, альтернативно, в коде, вызывающем ваш код.

Есть несколько моментов, которые следует избегать включения утверждений в производственный код: 1. Вы не хотите, чтобы ваш конечный пользователь видел сообщение типа «Сбой ASSERTION» строки MyPrivateClass.cpp 147. Конечный пользователь - НЕ , вы - инженер QA. 2. ASSERTION может повлиять на производительность

Однако есть одна веская причина оставить утверждения: ASSERTION может влиять на производительность и время, и, к сожалению, это иногда имеет значение (особенно во встроенных системах).

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

~ Ицик

0 голосов
/ 20 августа 2008

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

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

0 голосов
/ 20 августа 2008

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

Предлагаю пример

file = create-some-file();
_throwExceptionIf( file.exists() == false, "FILE DOES NOT EXIST");

против

file = create-some-file();
ASSERT(file.exists());

Как приложение будет обрабатывать утверждение? Я предпочитаю старый try catch метод устранения фатальных ошибок.

0 голосов
/ 20 августа 2008

Утверждение является ошибкой, чисто и просто и поэтому должно обрабатываться как единое целое.

Так как ошибка должна быть обработана в режиме деблокирования, вам действительно не нужны утверждения.

Основным преимуществом для утверждений, которое я вижу, является условный разрыв - их гораздо проще настроить, чем сверлить в окнах VC для настройки чего-то, что занимает 1 строку кода.

...