编写高质量C语言代码--assert yourself
来源:互联网 发布:2017日本就业率数据 编辑:程序博客网 时间:2024/05/01 13:40
C语言中assert功能强大,人称“断言”,如语句assert ( expression ),即断言expression始终为true, 若为false,则程序运行失败。
但是,assert ( expression ) 看似function,但它其实是macro, 而且只是一个debug-only的宏,即只有在定义DEBUG宏的情况下才有用。但是它却是一个强大的高度工具,而且也是编码bug-free的code的有力助手。
举个例子,有以下这样一个function:
example 1:
/* memcpy -- copy a nonoverlapping memory block */void* memcpy(void* pvTo, void* pvFrom, size_t size){byte* pbTo = (byte*)pvTo;byte* pbFrom = (byte*)pvFrom;while(size-- > 0)*pbTo = *pvFrom;return(pvTo);}
有经验的programmer一看就知道这是一个有bug的function。如果如此应用:
1.
memcpy(NULL, pvFrom, size);
2.
memcpy(pvTo, NULL, size);
就会出现问题。NULL是0,而对0地址解引用会出现什么事?SO BAD!
那么怎么办呢?在对pbTo与pvFrom解引用之前进行指针检查,进行如下改变:
example 2 :
/* memcpy -- copy a nonoverlapping memory block */void* memcpy(void* pvTo, void* pvFrom, size_t size){byte* pbTo = (byte*)pvTo;byte* pbFrom = (byte*)pvFrom;if(pvTo == NULL || pvFrom == NULL){fprintf(stderr, "Bad args in memcpy\n");abort();}while(size-- > 0)*pbTo = *pvFrom;return(pvTo);}OK, Perfect !但是身为一个持有完美主义的coder,似乎这样的代码不是那么一回事。有人教导我们,编写代码的时候要有两个版本:Debug Version and Ship Version。我们新加的语句好像是Debug Version里的吧,怎么能让它出现在Ship Version里呢?于是乎:
example 3:
/* memcpy -- copy a nonoverlapping memory block */void* memcpy(void* pvTo, void* pvFrom, size_t size){byte* pbTo = (byte*)pvTo;byte* pbFrom = (byte*)pvFrom;#ifdef DEBUGif(pvTo == NULL || pvFrom == NULL){fprintf(stderr, "Bad args in memcpy\n");abort();}#endifwhile(size-- > 0)*pbTo = *pvFrom;return(pvTo);}这下没问题了吧?嗯,我们的主角assert呢?怎么没有?别急,马上就来,有句话不是说:英雄总是最后登场的嘛。注意我们加的Debug语句不就是在测试pvTo与pvFrom不为NULL吗?这不就是assert的功能!So:
example 4:
/* memcpy -- copy a nonoverlapping memory block */ void* memcpy(void* pvTo, void* pvFrom, size_t size) { byte* pbTo = (byte*)pvTo; byte* pbFrom = (byte*)pvFrom; assert(pvTo != NULL && pvFrom != NULL); while(size-- > 0) *pbTo = *pvFrom; return(pvTo); }
嗯,好像可以了。但是~,如果pvTo与pvFrom指向的内存块是overlapped的呢?oh, no!所以还等断言pvTo与pvFrom是没有overlapped的。最终版登场:
example5:
/* memcpy -- copy a nonoverlapping memory block */ void* memcpy(void* pvTo, void* pvFrom, size_t size) { byte* pbTo = (byte*)pvTo; byte* pbFrom = (byte*)pvFrom; assert(pvTo != NULL && pvFrom != NULL); assert(pvTo >= pvFrom + size || pvFrom >= pbTo + size); while(size-- > 0) *pbTo = *pvFrom; return(pvTo); }
小结:请使用assert 来code您的程序!
- 编写高质量C语言代码--assert yourself
- 编写高质量C语言代码--API设计
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- Object-C 编写高质量代码
- 编写高质量Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量C代码一:数据
- 编写高质量的Objective-C代码
- 编写高质量的Objective-C代码
- 编写高质量代码
- 编写高质量代码
- iOS开发点滴-编写高质量的Objective-C代码
- 如何使用C语言来编写MSP430的高质量代码
- iostream
- 请问Eclipse中源码的中文部分都显示成乱码如何解决 .
- get out & clean
- 微博上对乔布斯的评价
- Hibernate一对一,一对多懒加载的要求
- 编写高质量C语言代码--assert yourself
- WindowsPhone程序运行时屏幕常亮
- 关于addEventListener和attachEvent的初步探讨
- Qt中可以把一个复杂对话框分为几部分的组件类
- aop的概念、原理、应用的地方
- SDK,API,MFC 三者的区别
- w3shool学习1-PHP 语法
- Java与SQL Server, MySql, Oracle, Access的连接方法以及一些异常 .
- latex输入单双引号