写这篇博客源于在阅读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)之间的区别;

  1. 一个程序错误是一个bug,永远不应该发生。
  2. 一个运行时错误是在程序运行的任何时候都可能会发生.

断言并不是一种处理运行时错误的机制。例如在需要输入正数的时候,用户输入了一个负数,如果用断言来检测这种情况就不是好的设计。对于这种情况需要用合适的错误检查和恢复处理的代码来进行处理。

再回到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

Writing Solid Code

你真的会使用assert吗?的更多相关文章

  1. 编程范式 episode 6 实现stack 栈功能_ to do

    //既然在这里开始,那就在这里结束. 实现stack 功能 ____coding _using subfunction to focus on the main aim of current func ...

  2. 简明python教程 --C++程序员的视角(九):函数式编程、特殊类方法、测试及其他

    函数式编程 Lambda exec,eval和assert语句,repr函数   lambda语句 用来创建简短的单行匿名函数 print_assign = lambda name, value: n ...

  3. (原+转)简明 Python 教程:总结

     简明 Python 教程 说明:本文只是对<简明Python教程>的一个总结.请搜索该书查看真正的教程. 第3章 最初的步骤 1. Python是大小写敏感的. 2. 在#符号右面的内容 ...

  4. 笔记|《简明Python教程》:编程小白的第一本python入门书

    <简明Python教程>这本书是初级的Python入门教材,初级内容基本覆盖,对高级内容没有做深入纠结.适合刚接触Python的新手,行文比较简洁轻松,读起来也比较顺畅. 下面是我根据各个 ...

  5. OO的奇妙冒险2

    OO的奇妙冒险 ~多线程入门与魔鬼的优化~ 目录 总体分析 作业内容分析 作业内容总结 互测的收获 公测互测bug分析与总结 优化分析 不太正经的个人自嗨 总体分析 公测 中测(基础与进阶): 这一单 ...

  6. python学习笔记比较全

    注:本笔记基于python2.6而编辑,尽量的偏向3.x的语法 Python的特色 1.简单 2.易学 3.免费.开源 4.高层语言: 封装内存管理等 5.可移植性: 程序如果避免使用依赖于系统的特性 ...

  7. 你真的了解load方法么?(转载)

    本文授权转载,作者:左书祺(关注仓库,及时获得更新:iOS-Source-Code-Analyze) 因为 ObjC 的 runtime 只能在 Mac OS 下才能编译,所以文章中的代码都是在 Ma ...

  8. python学习笔记 - assert用法

    [转自]http://blog.sina.com.cn/s/blog_76e94d210100vz37.html   1.assert语句用来声明某个条件是真的. 2.如果你非常确信某个你使用的列表中 ...

  9. 不加班的实践(1)——这真的该用try-catch吗?

    前言 我有个技能,就是把“我”说的听起来特别像“老子”. 以前是小喽啰的时候,会跟领导说“我!不加班.”,听起来就像“老子不加班!”一样.到最后发现,我确实没有把计划内的工作拖到需要加班才能完成,这个 ...

随机推荐

  1. 单片机C51串口发送、接收寄存器

    所以,发送和接收寄存器可使用同一地址,编写验证程序(发送和接收是独立空间):读取一个数(1)->发送一个数(2)->再读取得1则是独立空间 不知道STM32串口寄存器和C51串口寄存器是否 ...

  2. Angular2.X 笔记

    本文为原创,转载请注明出处: cnzt       文章:cnzt-p http://www.cnblogs.com/zt-blog/p/7762590.html 前提: angular-cli (前 ...

  3. DELPHI方法注释的标准写法

    /// <summary> /// 查询数据 /// </summary> /// <param name="accountno">帐套号< ...

  4. android CheckBox使用和状态获得

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...

  5. HeatMap(热图)的原理和实现

    先来看两张图: (1)10年世界杯决赛,冠军西班牙队中门将.后卫.中场及前锋的跑位热图 通过热图,我们可以很清楚的看出四个球员在比赛中跑动位置的差异. (2)历史地震震源位置的热图 也可以很清楚的看出 ...

  6. python 工具ScreenShoot

    环境:windows python3 # -*- coding: UTF-8 -*- import time import os, win32gui, win32ui, win32con, win32 ...

  7. 关于MP4视频拖动的原理与分析(一)

    本来想说说关于mp4和一些常见视频文件格式方面的历史. 如今想想没啥必要.毕竟本文是在讲关于mp4点播拖动方面的技术细节. 绪论,前言神马的显得有点多余. 说起MP4.不得不提"Digita ...

  8. SQL面试练习(MySql)

    创建测试数据库: /*如果已经存在此数据库,先删除*/ drop database if exists sqltest ; /*创建并设置编码为UTF-8*/ create database sqlt ...

  9. JAVA BigDecimal 高精度运算

    文章参考一位博友,由于时间太久忘了链接,见谅! public class BigDecimalUtils { private static final int DIV_SCALE = 10;// 除法 ...

  10. mysql的binlog详解

    什么是binlogbinlog日志用于记录所有更新了数据或者已经潜在更新了数据(例如,没有匹配任何行的一个DELETE)的所有语句.语句以“事件”的形式保存,它描述数据更改. binlog作用因为有了 ...