你真的会使用assert吗?
写这篇博客源于在阅读lighttpd源代码是遇到的一个关于assert应用的疑问。
在阅读lighttpd源代码时,发现比比皆是的对malloc的调用结果进行assert检查,比如:Buffer.c:

buffer* buffer_init(void) {
buffer *b;
b = malloc(sizeof(*b));
assert(b);
b->ptr = NULL;
b->size = 0;
b->used = 0;
return b;
}

这里的assert(b)似乎有问题,实际release版本在运行中难道不会发生malloc返回NULL的情况吗?之后在阅读《Writing Solid Code 》一书时找到了答案。
对assert的基本用法就不再累述了,下面总结一下assert的实际应用的Recommended practice吧:
1、要使用断言对函数参数进行确认
主要有以下情况:
- 指针不是NULL的断言;
- index值或size值不是负值或小于已知限值的断言;这一条也可以这么描述:要从程序中删去无定义的特性或者在程序中使用断言来检查出无定义特性的非法使用
2、每个断言必须在头文件中的函数功能描述的断言部分进行说明(不要浪费别人的时间 ─── 详细说明不清楚的断言 ),例如:
* Asserts:
* 'size' is no greater then LIMIT.
* 'format' is not NULL.
* The function result is no greater than LIMIT.
*/
如果没有断言, 写 “Nothing”:
* Asserts:
* Nothing
*/
(以上的格式也许严格了一些,不过如果真的这么做,对代码的可阅读性会很有帮助)
3、断言和错误校验的区别
正确使用断言,必须要清楚程序错误(program errors)和运行时错误(run- time errors)之间的区别;
- 一个程序错误是一个bug,永远不应该发生。
- 一个运行时错误是在程序运行的任何时候都可能会发生.
断言并不是一种处理运行时错误的机制。例如在需要输入正数的时候,用户输入了一个负数,如果用断言来检测这种情况就不是好的设计。对于这种情况需要用合适的错误检查和恢复处理的代码来进行处理。
再回到lighttpd中对malloc函数的返回值进行assert断言,我觉得也属于这个问题,这应该是一个运行时错误,而不是程序错误;所以,我觉得《C和指针》一书中对malloc返回NULL处理是通过一个错误检查分配器来处理的。
4、断言和bug
断言大致分为前置条件(Preconditions)、后置条件(Postconditions)、不变性条件(Invariants)
如果前置条件不成立,发生Assertion violations,则调用该函数的代码存在bug,需要尽快找到并解决;
如果后置条件不成立,发生Assertion violations,则(函数的)实现代码存在bug,需要尽快找到并解决;
例如:

void doBlah(int x)
{
assert(x!=0);
....
}

这段代码说明这个函数的调用不可能传入参数0,如果发生这种情况,说明调用这个函数的代码存在bug;
以上是自己的一点理解,欢迎高手指正!!!
参考:How to use assertions in C
你真的会使用assert吗?的更多相关文章
- 编程范式 episode 6 实现stack 栈功能_ to do
//既然在这里开始,那就在这里结束. 实现stack 功能 ____coding _using subfunction to focus on the main aim of current func ...
- 简明python教程 --C++程序员的视角(九):函数式编程、特殊类方法、测试及其他
函数式编程 Lambda exec,eval和assert语句,repr函数 lambda语句 用来创建简短的单行匿名函数 print_assign = lambda name, value: n ...
- (原+转)简明 Python 教程:总结
简明 Python 教程 说明:本文只是对<简明Python教程>的一个总结.请搜索该书查看真正的教程. 第3章 最初的步骤 1. Python是大小写敏感的. 2. 在#符号右面的内容 ...
- 笔记|《简明Python教程》:编程小白的第一本python入门书
<简明Python教程>这本书是初级的Python入门教材,初级内容基本覆盖,对高级内容没有做深入纠结.适合刚接触Python的新手,行文比较简洁轻松,读起来也比较顺畅. 下面是我根据各个 ...
- OO的奇妙冒险2
OO的奇妙冒险 ~多线程入门与魔鬼的优化~ 目录 总体分析 作业内容分析 作业内容总结 互测的收获 公测互测bug分析与总结 优化分析 不太正经的个人自嗨 总体分析 公测 中测(基础与进阶): 这一单 ...
- python学习笔记比较全
注:本笔记基于python2.6而编辑,尽量的偏向3.x的语法 Python的特色 1.简单 2.易学 3.免费.开源 4.高层语言: 封装内存管理等 5.可移植性: 程序如果避免使用依赖于系统的特性 ...
- 你真的了解load方法么?(转载)
本文授权转载,作者:左书祺(关注仓库,及时获得更新:iOS-Source-Code-Analyze) 因为 ObjC 的 runtime 只能在 Mac OS 下才能编译,所以文章中的代码都是在 Ma ...
- python学习笔记 - assert用法
[转自]http://blog.sina.com.cn/s/blog_76e94d210100vz37.html 1.assert语句用来声明某个条件是真的. 2.如果你非常确信某个你使用的列表中 ...
- 不加班的实践(1)——这真的该用try-catch吗?
前言 我有个技能,就是把“我”说的听起来特别像“老子”. 以前是小喽啰的时候,会跟领导说“我!不加班.”,听起来就像“老子不加班!”一样.到最后发现,我确实没有把计划内的工作拖到需要加班才能完成,这个 ...
随机推荐
- NSURLConnection和NSMutableURLRequest 实现同步、异步请求
我是走向ios的一个小书童,我有很多不懂的,新鲜的知识去学习,去掌握! 我首先要吐槽一下: 那些不负责的博友!你分享知识本来是好事!可是你直接Control+V就是你的不对了! 尼玛,直接Contro ...
- 【转】利用shell命令操作Memcached
原文: 张宴的博客 —— http://zyan.cc/post/384/ -------------------------------------------------------------- ...
- SolidEdge如何复制特征 建立类似于UG 块的概念
直接Ctrl+C和Ctrl+V可以实现特征的复制粘贴 按N键可以改变特征方向 已经复制完成的特征要进行定位,则右击该特征,编辑轮廓,可以进行聪慧尺寸的标注 使用特征库的方式,就像UG的块一样, ...
- fetch 函数分装
1.fetch /** * 封装 fetch */ import { hashHistory } from 'react-router'; export default function reques ...
- Android Problem- android.content.res.Resources$NotFoundException: String resource ID #0xa
在使用listview时出现错误android.content.res.Resources$NotFoundException: String resource ID #0xa 经查证是在调用Text ...
- XUtils BitmapUtils 改造以加入drawable支持
=== XUtilsBitmapUtils 改造以加入drawable支持 === # XUtils 简单介绍 XUtils 是一套少有的早期国产安卓框架, 其源于AFinal, 文件夹结构也与之相似 ...
- Effective C++ 条款八 别让异常逃离析构函数
class DBConn //这个class用来管理DBConnction对象 { public: //自己设计一个新的DBConn接口 方法3 void close() { db.close() ...
- zedboard中OLED源码
#include <stdio.h> #include "platform.h" #include "xil_types.h" #include & ...
- Oracle创建索引的原则(转)
Oracle 建立索引及SQL优化 数据库索引: 索引有单列索引复合索引之说 如何某表的某个字段有主键约束和唯一性约束,则Oracle 则会自动在相应的约束列上建议唯一索引.数据库索引主要进行提高访问 ...
- 基于TCP应用协议/端口