编写高质量C语言代码--assert yourself


        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 DEBUG
	if(pvTo == NULL || pvFrom == NULL){
		fprintf(stderr, "Bad args in memcpy\n");
		abort();
	}
#endif

	while(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您的程序!


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值