Как поместить assert в релизные сборки на C/C++

Мне нужно только запустить сборку корабля, и мне нужно подтвердить определенное условие в сборке выпуска, чтобы увидеть, устранена ли проблема. Как это сделать?


person Community    schedule 06.03.2009    source источник
comment
Какая платформа? Windows и Visual Studio?   -  person Peter Mortensen    schedule 28.09.2009
comment
Обычно не рекомендуется хранить утверждения в сборках Release. Однако у вас может быть веская причина для этого; тем не менее, его также можно не называть утверждением, и в этом случае он не должен использовать те же вызовы функций.   -  person moala    schedule 02.02.2012
comment
Почему бы вместо этого не использовать простое условие? Подумайте, что должна делать ваша программа, если утверждение не выполняется. Вы не должны просто вызывать std::abort в релизной сборке. Если вы разрабатываете приложение, сгенерируйте исключение. Если вы разрабатываете библиотеку, предоставьте отладочную сборку.   -  person Qw3ry    schedule 28.05.2018


Ответы (7)


Отмените определение макроса NDEBUG — вы можете сделать это локально вокруг утверждений, которые вы хотите оставить в сборке:

#undef NDEBUG
#include <assert.h>   // reinclude the header to update the definition of assert()

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

person Michael Burr    schedule 06.03.2009
comment
если assert.h включен в файл pch, это может не сработать. - person baye; 07.03.2009
comment
Только что попробовал - не всегда получается. Если я поставлю это в качестве первых двух строк в моем .cpp, это ничего не сделает, но оно работает, когда я помещаю его чуть выше моего main(). - person Anton Daneyko; 13.12.2009
comment
Тогда кажется, что что-то должно переопределять NDEBUG и снова включать assert.h (возможно, какой-то другой заголовок, который включается). - person Michael Burr; 14.12.2009

Почему бы просто не определить свой собственный assert:

#define assert(x) MessageBox(...);
person baye    schedule 07.03.2009
comment
Проголосовал за, потому что это единственное здравое предложение здесь. Хотя рекомендую указать номер строки, а также объяснение, что пошло не так. Хотя следующим делом также является разработка собственной аварийной системы, чтобы, когда происходит утверждение, вы делали дамп памяти, который автоматически отправлялся вам. - person Chad; 28.09.2009
comment
Мне это нравится, но я хотел бы сделать одно предложение с опозданием на шесть лет - используйте другое имя для вашего утверждения, что вы хотели бы существовать в выпусках и отладочных сборках, например ndbgassert или подобных. Таким образом, вы можете выбрать между двумя. - person Russell Greene; 08.08.2015
comment
Как утвердить MessageBox?? Разве он не должен сначала проверить условие? - person yairchu; 15.11.2017

Просто вызовите непосредственно ту часть определения макроса assert, которая активна в режиме выпуска.

Вы можете найти очень полезные определения утверждений в C++ в этой замечательной статье Миро. Самек (PDF). Затем вы можете немного изменить их, чтобы удовлетворить ваши потребности. Например, вы можете создать другой макрос, release_assert, который делает то же самое, что и assert, но независимо от того, находится ли он в режиме выпуска или в режиме отладки.

person Daniel Daranas    schedule 10.03.2009
comment
Но это определяется реализацией. Вы не можете сделать это портативно. - person Timmmm; 26.03.2018

Поведение ASSERT по умолчанию состоит в том, чтобы прервать программу в конфигурации отладки, но обычно это становится неработоспособным в конфигурации выпуска. Я полагаю, что он делает это, проверяя наличие макроса препроцессора NDEBUG. Я сейчас не на работе, поэтому проверить не могу.

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

Однако в целом ASSERT следует использовать только для предварительных условий программирования и никогда для обработки сбоев в поставляемом программном обеспечении. Вы хотите быстро выйти из строя во время разработки, но изящно перед пользователем.

person LeopardSkinPillBoxHat    schedule 06.03.2009

Мне нравится определять его так, чтобы он вызывал своего рода assert_exception, полученный из std::runtime_error. Затем поймайте его где-нибудь и сделайте что-нибудь полезное.

person Zan Lynx    schedule 15.05.2009

На самом деле - я бы согласился отправить отладочную версию, если вы можете с ней жить. Если вам не нужна производительность релизной версии, используйте файл debug. Как правило, в нем меньше ошибок (это грубое упрощение, и если ваша программа свободна от ошибок, простое переключение на выпуск не меняет этого, но из-за того, что компилятор делает в режиме отладки, ошибки могут не возникать и/или иметь менее тяжелые последствия).

Возможно, также возможно оптимизировать только критические по времени части вашей программы.

Это также может упростить отладку.

person Tobias Langner    schedule 28.09.2009
comment
Что ж, в Visual C++ вы не можете легально доставлять среды выполнения отладки C++, поэтому доставка двоичных файлов отладки клиенту может быть проблемой, если вы компилируете среды выполнения DLL (т. е. переключатели /MD или /MDd). - person paercebal; 25.09.2011
comment
Несмотря на то, что за этот ответ проголосовали отрицательно, я считаю, что он затрагивает важный момент, а именно идею о том, что изменение набора переменных между тем, что разработчик тестирует в первую очередь [отладочная версия], и тем, что выпущено, не обязательно хорошая идея. Опытные разработчики подтвердят, что версии Release и Debug часто ведут себя по-разному. - person Cameron; 08.02.2014

При использовании Visual Studio вы можете отменить определение прекомпилятора NDEBUG, чтобы активировать утверждения в сборке Release.

Например, вы можете установить $(undefesTheNDEBUG) в настройках Projekt для параметра /U, а затем определить переменную среды undefesTheNDEBUG в NDEBUG (SET undefesTheNDEBUG=NDEBUG) или передать ее вместе с msbuild (/p:undefesTheNDEBUG=NDEBUG)

person Marco Kinski    schedule 29.03.2011