Мне нравится определять свои собственные макросы утверждений. Я делаю два теста ASSERT всегда (даже для оптимизированных сборок), а DASSERT влияет только на отладочные сборки. Возможно, вы захотите установить значение по умолчанию ASSERT, но если что-то дорогое для тестирования, или утверждения внутри внутренних циклов чувствительных к производительности областей можно изменить на DASSERT.
Кроме того, помните, что утверждения следует использовать только для абсолютно бессмысленных условий, которые указывают на логическую ошибку в вашей программе и из которой вы не можете восстановиться. Это проверка вашей правильности программирования. Утверждения НИКОГДА не должны использоваться вместо обработки ошибок, исключений или надежности, и вы никогда не должны утверждать что-либо, связанное с искаженным или неправильным вводом пользователя - такие вещи должны обрабатываться изящно. Утверждение - это просто контролируемый сбой, когда у вас есть возможность вывести дополнительную информацию об отладке.
Вот мои макросы:
/// ASSERT(condition) checks if the condition is met, and if not, calls
/// ABORT with an error message indicating the module and line where
/// the error occurred.
#ifndef ASSERT
#define ASSERT(x) \
if (!(x)) { \
char buf[2048]; \
snprintf (buf, 2048, "Assertion failed in \"%s\", line %d\n" \
"\tProbable bug in software.\n", \
__FILE__, __LINE__); \
ABORT (buf); \
} \
else // This 'else' exists to catch the user's following semicolon
#endif
/// DASSERT(condition) is just like ASSERT, except that it only is
/// functional in DEBUG mode, but does nothing when in a non-DEBUG
/// (optimized, shipping) build.
#ifdef DEBUG
# define DASSERT(x) ASSERT(x)
#else
# define DASSERT(x) /* DASSERT does nothing when not debugging */
#endif