clpusplus /assert
cppreference /assert
Part1 Assert
assert旨在捕获程序员的编程错误(例如传入非法参数),而不是用户错误或运行时错误(如返回错误值或在 C++ 中抛出异常),因为它通常在程序退出调试阶段后被禁用。在程序运行时,一旦遇到断言不成立,程序即会报错终止,以方便程序调试。
assert是一个function-like marco,那么我们在程序中中调用assert(condition),编译器就会去看assert的宏定义,这个宏定义是在编译时处理好的。即:
- 如果当前没有定义
NDEBUG
,则执行# define assert(condition) /*implementation defined*/
;
- if condition 计算结果为 0,说明断言失败,程序崩溃:assert在standard error output中写入一条诊断信息,并调用std::abort终止程序执行。
- else,继续执行
- 如果定义了
NDEBUG
,则执行# define assert(condition) ((void)0)
,即assert不做任何事情。
#ifdef NDEBUG //如果定义了NDEBUG
# define assert(condition) ((void)0) //assert被定义成0
#else //否则
# define assert(condition) \ //宏定义常用技巧:使用‘\’表示分行
/*implementation defined*/
#endif //条件预编译结束
以下是三点解释:
-
宏assert的定义依赖于另一个宏
NDEBUG
。assert使用太多会影响系统性能,因此需要通过宏,把assert编译成debug版本和release版本。尽管NDEBUG
不是标准库中的宏,但是基本上编译器都在实现<cassert>的时候对其做了定义,因此编程的时候也要先#include<cassert>
再使用。如果定义了NDEBUG
,说明当前是release版本,不执行assert。