Действует ли 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() очень легко неправильно использовать или использовать не в том месте.

Другие вопросы по тегам