assert 实现分析

一直以来,对于assert的实现总是不太理解,现在深入assert背后的代码,总算对assert的实现有了一个清醒的认识。

assert基于宏定义与宏展开实现。首先介绍一下assert的功能:它能够断言给定表达式是否为true。如果为true,则对应assert的代码会转换为static_cast<void>(0),即一条空语句,assert不执行任何操作,否则assert对应的代码会展开为__assert_fail (__STRING(expr), __FILE__, __LINE__, __func__)),使用expr参数,源代码名,assert所在的行数以及函数名调用__assert_fail函数,输出错误信息,并且因为断言出错而终止程序。请注意,在调用函数__assert_fail时,assert将传入的参数转换为字符串输入,这一点只需查看__STRING(x)的定义:#define __STRING(x) #x即可明白。

我们知道,在编译源代码的时候,如果我们定义了NDEBUG,那么assert不会起任何作用,哪怕传入的参数为false,这是为什么呢?因为在assert外层还有一个宏判断语句,如果定义了NDEBG,那么assert语句统一转换成static_void<void>(0)进行处理,所以不会对传入的参数进行任何判断。

下面附上相关代码,相信你现在会对assert有更加清晰的认识!

// (为了便于阅读,代码进行了部分修改)
#define __STRING(x) #x #ifdef NDEBUG
# define assert(expr) (static_cast<void>(0))
#else
# define assert(expr) \
((expr) \
?static_cast<void>(0) \
: __assert_fail (__STRING(expr), __FILE__, __LINE__, __func__))
#endif
上一篇:Luogu P1776 宝物筛选_NOI导刊2010提高(02)(多重背包模版)


下一篇:Android网络开发之用tcpdump抓包