Мне нужно только запустить сборку корабля, и мне нужно подтвердить определенное условие в сборке выпуска, чтобы увидеть, устранена ли проблема. Как это сделать?
Как поместить assert в релизные сборки на C/C++
Ответы (7)
Отмените определение макроса NDEBUG — вы можете сделать это локально вокруг утверждений, которые вы хотите оставить в сборке:
#undef NDEBUG
#include <assert.h> // reinclude the header to update the definition of assert()
или делайте все, что вам нужно, чтобы ваш процесс сборки не определял макрос NDEBUG в первую очередь.
assert.h
(возможно, какой-то другой заголовок, который включается).
- person Michael Burr; 14.12.2009
Почему бы просто не определить свой собственный assert:
#define assert(x) MessageBox(...);
ndbgassert
или подобных. Таким образом, вы можете выбрать между двумя.
- person Russell Greene; 08.08.2015
Просто вызовите непосредственно ту часть определения макроса assert
, которая активна в режиме выпуска.
Вы можете найти очень полезные определения утверждений в C++ в этой замечательной статье Миро. Самек (PDF). Затем вы можете немного изменить их, чтобы удовлетворить ваши потребности. Например, вы можете создать другой макрос, release_assert
, который делает то же самое, что и assert, но независимо от того, находится ли он в режиме выпуска или в режиме отладки.
Поведение ASSERT по умолчанию состоит в том, чтобы прервать программу в конфигурации отладки, но обычно это становится неработоспособным в конфигурации выпуска. Я полагаю, что он делает это, проверяя наличие макроса препроцессора NDEBUG. Я сейчас не на работе, поэтому проверить не могу.
Я думаю, что самый простой способ обойти это — изменить конфигурацию отладки, чтобы перевести все оптимизации на тот же уровень, что и выпуск (O2 из памяти), а затем заново собрать свое программное обеспечение. Это даст вам эквивалентную производительность и скорость сборки Release, но по-прежнему будет определять макрос препроцессора NDEBUG, что означает, что все неудачные ASSERT по-прежнему будут вызывать прерывание программы. Просто не забудьте позже изменить уровень оптимизации обратно, иначе у вас возникнут проблемы с отладкой в конфигурации отладки.
Однако в целом ASSERT следует использовать только для предварительных условий программирования и никогда для обработки сбоев в поставляемом программном обеспечении. Вы хотите быстро выйти из строя во время разработки, но изящно перед пользователем.
Мне нравится определять его так, чтобы он вызывал своего рода assert_exception, полученный из std::runtime_error. Затем поймайте его где-нибудь и сделайте что-нибудь полезное.
На самом деле - я бы согласился отправить отладочную версию, если вы можете с ней жить. Если вам не нужна производительность релизной версии, используйте файл debug. Как правило, в нем меньше ошибок (это грубое упрощение, и если ваша программа свободна от ошибок, простое переключение на выпуск не меняет этого, но из-за того, что компилятор делает в режиме отладки, ошибки могут не возникать и/или иметь менее тяжелые последствия).
Возможно, также возможно оптимизировать только критические по времени части вашей программы.
Это также может упростить отладку.
При использовании Visual Studio вы можете отменить определение прекомпилятора NDEBUG, чтобы активировать утверждения в сборке Release.
Например, вы можете установить $(undefesTheNDEBUG) в настройках Projekt для параметра /U, а затем определить переменную среды undefesTheNDEBUG в NDEBUG (SET undefesTheNDEBUG=NDEBUG) или передать ее вместе с msbuild (/p:undefesTheNDEBUG=NDEBUG)
std::abort
в релизной сборке. Если вы разрабатываете приложение, сгенерируйте исключение. Если вы разрабатываете библиотеку, предоставьте отладочную сборку. - person Qw3ry   schedule 28.05.2018