一直以来,对于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

assert 实现分析的更多相关文章

  1. ASSERT_VALID和ASSERT宏分析

    这个宏都是MFC的调试宏. ASSERT_VALID宏用来在运行时检查一个对象的内部合法性,比如说现在有一个学生对象,我们知道每个学生的年龄一定大于零,若年龄小于零,则该学生对象肯定有问题. 事实上, ...

  2. 2017-12-09 JavaScript实现ZLOGO子集: 测试用例

    续前文JavaScript实现ZLOGO子集: 前进+转向. 在添加新功能之前, 先添加测试用例, 以应对日益复杂的代码. 选择使用QUnit编写运行测试用例. 暂时对比较复杂和I/O无关的部分进行测 ...

  3. 源码分析六(org.springframework.util包之Assert类)

    一:抽象类Assert 抽象类不能够实例化对象,但是可以被继承,Assert类是功能类,所以方法都是static修饰 所以可以直接  类名.方法 调用. public abstract class A ...

  4. 从netty-example分析Netty组件续

    上文我们从netty-example的Discard服务器端示例分析了netty的组件,今天我们从另一个简单的示例Echo客户端分析一下上个示例中没有出现的netty组件. 1. 服务端的连接处理,读 ...

  5. SQLite3源程序分析之查询处理及优化

    前言 查询处理及优化是关系数据库得以流行的根本原因,也是关系数据库系统最核心的技术之一.SQLite的查询处理模块很精致,而且很容易移植到不支持SQL的存储引擎(Berkeley DB最新的版本已经将 ...

  6. SQLite3源程序分析之虚拟机

    前言 最早的虚拟机可追溯到IBM的VM/370,到上个世纪90年代,在计算机程序设计语言领域又出现一件革命性的事情——Java语言的出现,它与c++最大的不同在于它必须在Java虚拟机上运行.Java ...

  7. Netty源码分析之客户端启动过程

    一.先来看一下客户端示例代码. public class NettyClientTest { public void connect(int port, String host) throws Exc ...

  8. C 标准库系列之assert.h

    先简单介绍一下<assert.h>头文件,该头文件的目的便是提供一个宏assert的定义,即可以在程序必要的地方使用其进行断言处理:断言在程序中的作用是当在调试模式下时,若程序给出的前提条 ...

  9. Duilib源码分析(四)绘制管理器—CPaintManagerUI—(前期准备二)

    接下来,我们继续分析UIlib.h文件中余下的文件,当然部分文件可能顺序错开分析,这样便于从简单到复杂的整个过程的里面,而避免一开始就出现各种不理解的地方. 1. UIManager.h:UI管理器, ...

随机推荐

  1. 使用NGUI进行类似Button的操作

    下面例子以Label和Sprite为例,进行说明如何在NGUI中对控件添加单击响应的事件方法. 首先在UIRoot下添加Label控件,然后Scene场景中右键Label-->Attach--& ...

  2. CSS样式覆盖规则

    有一下问题, 想让下面的border生效 ,#比. 优先级高, #navigator { height: 100%; width: 200; position: absolute; left: 0; ...

  3. POJ2718 递归套递归

    就是给你一个数,排列组合,然后问如何排列之间的差值最小. 我之前的想法是一个递归,然后两个for循环枚举L1和L2,结果TLE了,然后想了一下剪枝发现没办法剪,然后看了一下别人的代码,用了next_p ...

  4. Android Studio 修改主题

    http://jingyan.baidu.com/article/6f2f55a18040aeb5b93e6cb4.html

  5. 老问题:Android子线程中更新UI的3种方法

    在Android项目中经常有碰到这样的问题,在子线程中完成耗时操作之后要更新UI,下面就自己经历的一些项目总结一下更新的方法: 方法一:用Handler 1.主线程中定义Handler: Handle ...

  6. HDU 1815 Building roads

    二分答案 + 2-SAT验证 POJ 稳过,HDU C++ 超时,G++ 550ms左右AC #include<cstdio> #include<cstring> #inclu ...

  7. WebDriver(Selenium2) 判断页面是否刷新的方法

    http://uniquepig.iteye.com/blog/1568208 public static boolean waitPageRefresh(WebElement trigger) { ...

  8. docker固定IP地址重启不变

    docker固定IP地址重启不变 代码地址 https://github.com/lioncui/docker-static-ip 宿主机IP为  10.6.17.12 docker IP为 10.6 ...

  9. libthread_db

    http://timetobleed.com/notes-about-an-odd-esoteric-yet-incredibly-useful-library-libthread_db/

  10. 缩短url-url短地址链接

    之前给合作方二维码时隐藏的url过长,导致合作方提出在打印的时候打印不出来的问题,要求url长度在50字节内,所以写了缩短url功能. var url = string.Format("{0 ...