断言
assert
和 static_assert
都是 assert.h
中定义的宏。
assert
的定义取决于标准库未定义的宏 NDEBUG
。如果定义了 NDEBUG
,assert
是一个 no-op:
#ifdef NDEBUG
# define assert(condition) ((void) 0)
#else
# define assert(condition) /* implementation defined */
#endif
关于 NDEBUG
是否应该总是用于生产编辑的意见不一。
- 亲阵营认为
assert
调用abort
并且断言消息对最终用户没有帮助,因此结果对用户没有帮助。如果你有检查生产代码的致命条件,你应该使用普通的if/else
条件和exit
或quick_exit
来结束程序。与abort
相比,这些允许程序进行一些清理(通过atexit
或at_quick_exit
注册的功能)。 - 该阵营认为,
assert
调用永远不应该在生产代码中激活,但如果他们这样做,则检查的条件意味着存在严重错误,如果执行继续,程序将会出错。因此,最好让断言在生产代码中处于活动状态,因为如果它们触发,那么地狱已经松动了。 - 另一个选择是使用一个自制的断言系统,它总是执行检查,但在开发(适当的时候)和生产(“意外的内部错误 - 请联系技术支持”可能更合适)之间处理错误的方式不同。
static_assert
扩展为 _Static_assert
这是一个关键字。在编译时检查条件,因此 condition
必须是常量表达式。在开发和生产之间不需要对此进行不同的处理。