前言:
公元2017年5月28号晚上8点多左右的时间,被一次网络面试刺激了,同时也意识到,个人的编程功力退步。因此,本着“生气不如争气”的原则,痛定思痛。决定从此开始逐步补充“功力”,于是开始定下一个小目标。重新阅读两本经典著作《C语言程序设计》和《数据结构与算法分析-C语言描述》。并且阅读分析GNU C标准库的实现。本系列文章为阅读gnulibc库的笔记。
一、概述:
assert断言。防御式编程使用,“编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作是
异常处理的一种高级形式。”【摘自:
http://baike.baidu.com/link?url=ViADDthCRAFpAmscmKFGI9q5XzW9RDBwHHi8vUf1X3m3GjXjj6poeEf9BeMEXsoGA1SNPQsphF29bGpsTe8x6a】
而C语言的断言通过assert宏定义来实现,使用的时候通过指令:
#include<assert.h>包含头文件。
然后在需要使用断言的地方通过类似代码实现:
assert(exp)。exp为假设成立的表达式,类似“x>0 “,“A==1”等等。
二、使用场景:
断言一般用来代码调试使用,断言使用太多对程序执行效率也会产生一定的影响,故此可以通过开关进行关闭 。 如果使用GNU的编译器,通过宏定义”NDEBUG“进行控制,程序代码定义了NDEBUG,则断言代码直接被编译器过滤掉,否则,断言代码有效。
三、gnulib库实现代码分析:
以glibc-2.25为参考,实现宏定义的代码分别包括 include目录的assert.h头文件和assert目录下的相关头文件和实现文件。
1)glibc-2.25/include/assert.h
这个是我们程序代码中包含的头文件。该头文件内部仅仅是对assert/assert.h头文件中的三个函数进行定义。以下是头文件的详细内容:
1 #include <assert/assert.h>
2
3 #ifndef _ISOMAC
4 /* This prints an "Assertion failed" message and aborts.
5 In installed assert.h this is only conditionally declared,
6 so it has to be repeated here. */
7 /* 输出"Assertion failed"消息并退出.
8 * 如果安装了assert.h,这个代码仅仅是条件声明,
9 * 因此必须被取代.
10 */
11 extern void __assert_fail (const char *__assertion, const char *__file,
12 unsigned int __line, const char *__function)
13 __THROW __attribute__ ((__noreturn__)); //__THRO