Действует ли assert() как функция идентификации в режиме выпуска?
Эта библиотека использует assert()
как будто это функция идентификации в режиме релиза (когда определен NDEBUG). Проблема в том, что какой-то важный код обернут assert()
и мои тесты сработали при выполнении в режиме выпуска, потому что эти важные части не были вызваны. Пример этого можно найти здесь, где генератор случайных байтов ничего не будет генерировать и вызовет бесконечный цикл.
Личный анекдот: мне не нравится assert()
и я лично не использую это из-за этих проблем неясности. Я слышал о многих проектах, которые имели серьезные ошибки из-за этого, совсем недавно EOS, когда их модульные тесты не обнаружили некоторые массивы вне диапазона, потому что NDEBUG был определен в режиме выпуска, и он не срабатывал. Документация, кажется, не ясна по этому вопросу. Есть ли assert()
выступать в роли личности вообще?
Эта библиотека (libbtc), кажется, широко используется, и я не понимаю, почему разработчик сделал это. Это ужасная ошибка, и я должен раскошелиться и удалить все эти утверждения? Или это какая-то вещь C, которая не совместима с C++? Может кто-нибудь объяснить, пожалуйста, правильный курс действий здесь?
Я использую Clang 6.
2 ответа
С https://en.cppreference.com/w/cpp/error/assert:
Если
NDEBUG
определяется как имя макроса в той точке исходного кода, где<cassert>
включен, то утверждать ничего не делает.
Не кладите ничего в assert
у которого есть побочные эффекты, от которых вы зависите. Они не произойдут, когда вы скомпилируете релиз, и изменят поведение вашей программы.
Похоже, автор библиотеки неправильно использовал assert и поместил функциональный код там, где он не принадлежал. Что касается ошибок из-за assert(), это происходит из-за неправильного понимания его цели или отсутствия дисциплины программирования. assert() используется для проверки того, что инварианты не нарушаются, не для функционального кода. assert() очень легко неправильно использовать или использовать не в том месте.