断言

assertstatic_assert 都是 assert.h 中定义的宏。

assert 的定义取决于标准库未定义的宏 NDEBUG。如果定义了 NDEBUGassert 是一个 no-op:

#ifdef NDEBUG
#  define assert(condition) ((void) 0)
#else
#  define assert(condition) /* implementation defined */
#endif

关于 NDEBUG 是否应该总是用于生产编辑的意见不一。

  • 亲阵营认为 assert 调用 abort 并且断言消息对最终用户没有帮助,因此结果对用户没有帮助。如果你有检查生产代码的致命条件,你应该使用普通的 if/else 条件和 exitquick_exit 来结束程序。与 abort 相比,这些允许程序进行一些清理(通过 atexitat_quick_exit 注册的功能)。
  • 该阵营认为,assert 调用永远不应该在生产代码中激活,但如果他们这样做,则检查的条件意味着存在严重错误,如果执行继续,程序将会出错。因此,最好让断言在生产代码中处于活动状态,因为如果它们触发,那么地狱已经松动了。
  • 另一个选择是使用一个自制的断言系统,它总是执行检查,但在开发(适当的时候)和生产(“意外的内部错误 - 请联系技术支持”可能更合适)之间处理错误的方式不同。

static_assert 扩展为 _Static_assert 这是一个关键字。在编译时检查条件,因此 condition 必须是常量表达式。在开发和生产之间不需要对此进行不同的处理。