先简单介绍一下<assert.h>头文件,该头文件的目的便是提供一个宏assert的定义,即可以在程序必要的地方使用其进行断言处理;断言在程序中的作用是当在调试模式下时,
若程序给出的前提条件没有满足或是没有达到预期预定的条件便会出现断言为假,此时程序会异常终止,调试时会挂在该断言失败处(即结果为false的断言位置)并打印或者显示断言
失败的消息。

  assert函数实际上是一个宏,glibc和微软的c标准库实现均是如此;如glibc的:
    # define assert(expr) \
    ((expr) \
    ? __ASSERT_VOID_CAST (0) \
    : __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION))

  可以看到该宏实际上是通过三目运算符,判断表达式expr的真假,执行相应的处理,当为真是执行__ASSERT_VOID_CAST(0),该函数实际上也是一个宏;
即# define __ASSERT_VOID_CAST static_cast<void>,其实际上什么也没有做,此外__assert_fail函数便是用以打印断言失败的消息并终止的函数;该函数参数分别为断言表达式,
当前的文件路径名,当前行号,以及断言函数名;而这些参数通过相应的宏提供。
__assert_fail函数内部调用__assert_fail_base,其提供格式化打印输出,__assert_fail_base内部分配堆空间存储格式化后的信息,并调用__fxprintf以及fflush向stderr
标准输出刷字符串;此后便释放该分配的堆空间,并调用abort终止程序;微软的提供了类似的实现,不过其针对Unicode和多字节提供不同的实现方式,当为Unicode时,其assert宏
失败时调用_assert函数,同样的_assert函数内部调用_set_error_mode来控制设置输出,sprintf格式化错误信息,此后通过GetStdHandle(STD_ERROR_HANDLE)获取到错误输出设备
并调用WriteConsole向该错误输出设备输出字符串信息,此后同样调用abort来终止程序;而当为多字节模式时,便调用_ftprintf以及fflush向stderr标准输出刷字符串;

  assert函数,其参数为int类型,故只要表达式可计算结果可以转化为int类型的均可。

  assert断言仅在Debug模式下有效,对于发行Release或者NDEBUG模式下其宏声明类似于# define assert(expr) (__ASSERT_VOID_CAST (0))或者#define assert(ignore) ((void)0);
即什么也不做,也包括表达式的值也不会计算,这个一定要切记!此处若使用不当可能引入BUG,导致调式和开发模式下程序有不同的表现行为。

  顺便提一下,abort函数也是C语言标准库stdlib.h中的一员。

  此外C11中提供了static_assert宏,若编译器支持C11,则建议使用该宏来进行断言处理,此外此后的C语言标准库分析均暂时不针对C11的标准库。

C 标准库系列之assert.h的更多相关文章

  1. 《C标准库》—之<assert.h>实现

    首先,贴出标准库中<assert.h>的实现源码: #undef assert #ifdef NDEBUG #define assert(test)((void)0) #else void ...

  2. C 标准库系列之locale.h

    locale.h 区域设置相关,主要针对时间日期.货币格式.字符控制.数字格式等以满足某区域的设置需要. locale设置类别主要包括以下几个宏定义的类别: LC_ALL:设置所有的类别: LC_CO ...

  3. C 标准库系列之errno.h

    errno.h 提供了一个整数全局变量errno,当系统调用或者库函数的错误事件发生时可能会修改该值,指明错误的原因,该值可在任何需要的地方被修改:一般情况不为0的值表示出现了异常或者错误. errn ...

  4. C 标准库系列之limits.h

    limits.h 类似于float.h,其定义了一些列类型的值的范围.限制值,也就是说该类型的值不可以大于该上界或者小于该类型值的下界: glibc中宏定义了一下的值: # define MB_LEN ...

  5. C 标准库系列之float.h

    float.h 内部主要包含了一系列的浮点数宏.指明可移植程序必要的常量:浮点数格式一般为Spxbe;其中S表示+-:p表示底数.b表示基数如2.8.10.16等进制,e为指数标识E或e: 在一般情况 ...

  6. C 标准库系列之ctype.h

    ctype.h 主要提供了一些函数用以测试字符或字符处理的功能函数:包括字符判断检测.字符转换: 目前ASCII字符可分为以下一些类型,如:大写.小写.字母.数字.十六进制.空白字符.可打印字符.控制 ...

  7. C 标准库系列之概述

    基本上很多编程语言都会提供针对语言本身的一系列的标准库或者包,当然C语言同样也有提供标准库,C语言的标准库是一系列的头文件的集合:如assert.h.ctype.h.errno.h.float.h.l ...

  8. 《C标准库》——之<ctype.h>

    在没读<ctype.h>的源码之前,我一直以为我们平时用的isalnum.isdigit.isalpha等这些函数,是靠判断写出来的. 比如: int isdigit(int c){ re ...

  9. 《C标准库》——之<stddef.h>

    <stddef.h>,顾名思义,就是标准定义.C语言里这个标准库里定义了一些类型,和宏定义. <stddef.h>的内容: 类型: ptrdiff_t : 是两个指针相减的结果 ...

随机推荐

  1. JavaScript中让Html页面中循环播放文字

    JavaScript中让Html页面中循环播放文字 <html> <head> <meta http-equiv="Content-Type" con ...

  2. 在Main方法中设置异常的最后一次捕捉

    在做Winfrom程序时,有时会遇到一个异常,可是这个异常不知道在什么地方发生的,程序会自动关闭,然后什么也没有了,在网上找到了一种方法,用来捕捉这种异常. 出现这种情况的原因是在程序中某些地方考虑不 ...

  3. windows 64位 安装apache+php+mysql

    1.下载PHP.Apache和Mysql软件以及VC库. 下面分别是PHP.Apache和Mysql的官网地址. PHP:http://windows.php.net/qa/ 注意 选择Thread ...

  4. git查看本地和创建分支、上传分支、提交代码到分支、删除分支等,git分支、git查看本地和创建分支以及上传分支到服务器

    以下是git命令行里边的命令操作 ##进入项目目录下 giscafer@Faronsince2016 /G/002_project $ cd Comments ##查看远程分支有哪些 giscafer ...

  5. jvm--4垃圾收集

    6. 垃圾收集GC (1)当需要排查各种内存溢出,内存泄漏等问题,当GC成为系统达到更高性能的瓶颈时,我们就需要对这些自动化的GC进行监控和调节. (2)PC计数器.本地方法栈.虚拟机栈,随方法或者线 ...

  6. MySQL索引类型总结和使用技巧以及注意事项

    索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable ...

  7. C和指针 第十七章 习题

    17.8 为数组形式的树编写模块,用于从树中删除一个值,如果没有找到,程序节点 ArrayBinaryTree.c // // Created by mao on 16-9-18. // #inclu ...

  8. User space 与 Kernel space

    学习 Linux 时,经常可以看到两个词:User space(用户空间)和 Kernel space(内核空间). 简单说,Kernel space 是 Linux 内核的运行空间,User spa ...

  9. winform 跨线程操作控件

    当进行winform的开发时,经常遇到用时比较久的操作,在传统的单线程程序中,用户必须等待这个耗时操作完成以后才能进行下一步的操作,这个时候,多线程编程就派上用场了,将这个耗时的操作放到一个新的子线程 ...

  10. SQL Server 积累

    2016-11-24 sql语句修改某表某字段的数据类型和字段长度: 问题是在修改老功能中暴露出来的,我修改了图片上传功能,结果报图片路径超出数据库字段规定长度,我检查数据库后发现之前设计数据库的人将 ...