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便可明白。code

咱们知道,在编译源代码的时候,若是咱们定义了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
相关文章
相关标签/搜索