Как полностью отключить вызовы assert()?

Мой код полон вызовов assert(condition). В отладочной версии я использую g++ -g, который запускает мои утверждения. Неожиданно те же утверждения запускаются и в моей релизной версии, скомпилированной без опции -g.

Как я могу полностью отключить свои утверждения во время компиляции? Должен ли я явно определять NDEBUG в любой сборке, которую я создаю, независимо от того, является ли она отладочной, выпускной или чем-то еще?


person Abruzzo Forte e Gentile    schedule 18.03.2011    source источник
comment
Немного не по теме: если вам нужна отладочная информация, -g эквивалентно -g2. -g3 может быть лучшим выбором, так как он предоставляет наиболее символическую информацию. Например, в -g3 будут доступны символические #define. Однако мне кажется, что некоторые цепочки инструментов задыхаются от -g3. Кроме того, многие внешние библиотеки также зависят от -DDEBUG для "отладочных" сборок (Posix подтверждает -DNDEBUG только для "выпускных" сборок).   -  person jww    schedule 04.09.2012


Ответы (5)


Вы должны #define NDEBUG (или использовать флаг -DNDEBUG с g++), это отключит утверждение, если оно определено до включения файла заголовка утверждения.

person GWW    schedule 18.03.2011
comment
должно быть до #include <assert.h>? - person Lei Yang; 30.03.2017
comment
@LeiYang Кажется, нужно добавить перед последним #include <assert.h>. - person user218867; 08.04.2018

Используйте 1_

7.2 Диагностика

1 Заголовок определяет макрос assert и ссылается на другой макрос,

ОТЛАДКА

который не определяется <assert.h>. Если NDEBUG определен как имя макроса в том месте исходного файла, куда он включен, макрос assert определяется просто как

#define assert(ignore) ((void)0)

Макрос assert переопределяется в соответствии с текущим состоянием NDEBUG каждый раз, когда включается <assert.h>.

person Prasoon Saurav    schedule 18.03.2011
comment
Привет! Если это правда, что когда я определяю -DNDEBUG, все равно вызов assert выполняет что-то, то есть ((void)0), будет ли это тратить минимальные циклы ЦП? Я думал, что это было сопоставлено просто ни с чем, то есть полностью НЕТ КОДА ... не так ли? - person Abruzzo Forte e Gentile; 18.03.2011
comment
@Abruzzo: я тоже так думал до сих пор, но если подумать, вместо этого останется пустой ;, что может быть проблематично, если, например, assert находится внутри if. Я уверен, что компилятор оптимизирует строки типа 0; подальше - person davka; 18.03.2011
comment
@Abruzzo, и, кстати, проверьте, позволяет ли ваша среда IDE или ваша система сборки указать шаблон по умолчанию для нового проекта. Затем вы можете определить NDEBUG в конфигурации Release каждого нового проекта. - person davka; 18.03.2011
comment
@Abruzzo Что ты имеешь в виду под отсутствием кода? В исполняемом файле не будет сгенерирован код ((void)0). И стандарт требует, чтобы assert можно было использовать везде, где может использоваться выражение с типом void, поэтому простая замена его без токенов не будет работать. - person James Kanze; 18.03.2011
comment
Компилятор оптимизирует его во время компиляции. Думайте об этом как о NOP. Бесполезные NOP удаляются, но это зависит от компилятора. Например, при компиляции кода MIPS могут быть файлы сборки, в которых есть NOP, которые остаются там, чтобы покрыть ветку и задержки загрузки там, где это необходимо для согласования инструкций с циклическими границами часов или другим неопределенным поведением. - person user2262111; 02.11.2018

Вы можете либо полностью отключить утверждения,

#define NDEBUG
#include <assert.h>

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

person dcn    schedule 18.03.2011

Флаг -g не влияет на работу assert, он просто обеспечивает доступность различных символов отладки.

Настройка NDEBUG — это стандартный (как в официальном стандарте ISO) способ отключения утверждений.

person Alnitak    schedule 18.03.2011

Да, определите NDEBUG в командной строке/системе сборки с опцией препроцессора/компилятора -DNDEBUG.

Это не имеет ничего общего с отладочной информацией, вставленной -g.

person Fred Foo    schedule 18.03.2011