Моя рекомендация: по умолчанию вы должны оставить их ON . Я говорю: «терпеть неудачу, терпеть неудачу рано» - и держать ваши исправления более приоритетными, чем функции.
Однако выбор также хорош - я не думаю, что один размер подходит для всех программ. По этой причине я использую несколько типов утверждений. Некоторые будут жить в релизе, некоторые нет. Я пишу много обнаружения ошибок, а также пишу много программ, критичных к производительности. Я не могу оставить кучу проверок диагностики и исправности в горячих путях сборок релизов.
К сожалению, это не может быть запоздалой мыслью (если, возможно, вы не готовы расставить приоритеты по качеству и тестировать в течение неограниченного времени). Если вы думаете об этом, единый / традиционный подход также не может быть запоздалой мыслью. Для любой модели лучше всего решить, будут ли утверждения или какие утверждения будут включены в выпуске до написания вашей программы.
Таким образом, основная общая форма модели двойного утверждения может выглядеть следующим образом:
#include <assert.h>
/*
MONDebugAssert assertion is active in debug and disabled in release.
Recommendation: Always define NDEBUG (or not) in your build settings,
and nowhere else.
*/
#if defined(NDEBUG)
#define MONDebugAssert(e) ((void)0)
#else
#define MONDebugAssert(e) \
(__builtin_expect(!(e), 0) ? __assert(#e, __FILE__, __LINE__) : (void)0)
#endif
/* MONAssert assertion is active at all times, including release builds. */
#define MONAssert(e) \
(__builtin_expect(!(e), 0) ? __assert(#e, __FILE__, __LINE__) : (void)0)
где __assert
- обработчик утверждения платформы.
Затем используется:
MONDebugAssert(0); // << will fail in debug, and not in release.
MONAssert(0); // << will fail in any case
Конечно, достаточно легко адаптироваться к вашим потребностям или создать варианты, в которых предполагается, что self
входит в область действия (например, NSAssert
).