随笔 - 119  文章 - 290  trackbacks - 0

博客搬家了哦,请移步
叫我abc

常用链接

留言簿(12)

随笔分类

我的博客

搜索

  •  

积分与排名

  • 积分 - 301920
  • 排名 - 84

最新评论

阅读排行榜

前不久看到一文章,说用assert的时候不要把非法情形和错误情形混淆了,错误始终是要处理的.
然后我review自己最近写的代码,愣是没有弄明白什么是非法什么是错误,难道错误不是非法么,非法不是错误么?
我本身用assert是相当频繁和随意的,但是经过这么一看,反而觉得原来那些assert的代码都要改成错误处理了...
花非花,雾非雾.

经过思考与实践,最终确定了规则.
非法情形,大部分你觉得有问题的地方,需要约束的地方,都可以认为可能存在非法情形.比如指针有效性,字符串长度,数值范围等等.更抽象的说,非法情形存在于动作开始执行前的状态中.
相对之,错误就是动作执行之后的结果,错误是针对执行结果的.
详细而言,当调用一个函数,进入函数体的时候,就进入了一个非法情形出现点,在这里,在执行任何具体的计算和动作之前,面对参数还有其他状态,你嗅到的任何东西都可以说是非法情形.然后函数开始执行,这里面所出现的任何(大多数)失败都是一种错误,需要进行处理.
需要着重强调的是,函数的执行结果(返回值)绝对是一种错误(如果返回值是那个意思的话),而不是非法状态.(考虑一种计算函数,它的返回结果限制在某个范围内,这是非法状态还是错误呢?我认为还是错误,虽然有些像非法状态,要进行更严格的处理和提示).

我极度强调在函数执行前确认非法状态,而不是当成错误处理(通常这种处理都是默默的,不透明的,不像assert那样嚣张-_-|||).因为我们写函数(接口)的目的,是希望能被正确的调用,而不是胡乱(导致局部或者整体状态混乱)的使用(为此我们居然要将assert写成错误处理的形式,以容忍各种白痴的调用行为).
但是有一些情形,在不得以的情况下,比如一个函数,要assert某个指针是有效的,然后才能执行某些动作,但是随后的执行状况是,极度可能在那个指针无效的时候却仍然不可避免的调用该函数,那么你就把assert简单的用if替换掉就是了,没什么难的.但是,第一次写下那个函数的时候,吓你一跳的assert永远是不二的选择,如果你直接就用了if之类的错误处理,后面出什么状况就不是那么显眼了.

正确的滥用assert吧,至少我是这么做的.

posted on 2006-07-15 18:35 LOGOS 阅读(2819) 评论(9)  编辑 收藏 引用

FeedBack:
# re: 滥用assert 2006-07-16 12:29 小明
既要有ASSERT(For DEBUG),又要有错误处理(For Release)
例如:
assert(p!=NULL);
if(p==NULL) return false;  回复  更多评论
  
# re: 滥用assert 2006-07-16 12:54 LOGOS
@小明
debug版本的目的,就是尽量去除bug和不安定的状态,release版本是用来发布的,不是用来处理那些本不应该出现的非法情形的.如果你真的那样做的话(用if),你一定会被繁琐死的.
另外,关于你举的例子,请看倒数第二段,第三段.

PS:我的只不过是一家之言,不一定是正确的.谢谢你的评论  回复  更多评论
  
# re: 滥用assert 2006-07-16 14:38 OOSKY
release版本时,非法即是错误,错误即是非法,assert有没有都木关系。  回复  更多评论
  
# re: 滥用assert 2006-07-16 14:52 小明
有个原则,在Release版本,不管发生什么,不要让程序crash掉。
当然,书写健壮的程序非常困难和繁琐,但这就是我们产品的价值所在,也是专业程序员要做到的

  回复  更多评论
  
# re: 滥用assert 2006-07-16 15:31 LOGOS
嗯.我知道各位的意思.各位都特别针对了release
而我的意思是,希望能将这种非法性杜绝在debug中,在assert的保护下进行测试,即使出现问题也能很快的定位到发生位置,然后进行代码修改.到了release版本中,这种非法性就认为不存在了,至少不能将其和错误混为一谈吧.  回复  更多评论
  
# re: 滥用assert 2006-07-21 11:36 chenjm
assert应该是指调用该函数的前提吧, 如果func(void* lpData)调用时允许lpData为NULL则不能用assert, 否则的话一定要用assert,一般来说, assert确实是用来在调试状态下检测那些错误的调用了函数的情况。  回复  更多评论
  
# re: 滥用assert 2006-07-29 11:05 LOGOS
写代码的时候仍然很烦躁,于是再次review大家的评论,发现了一个是使用assert还是老实处理的重要区别----"有个原则,在Release版本,不管发生什么,不要让程序crash掉."
所以使用assert之前,先考虑那个地方在release下是否会存在非法/错误情形,要为可能的crash负责.  回复  更多评论
  
# re: 滥用assert 2007-03-21 12:02 阿财
就算微软的word里面也充斥着大量的assert.
必要的时候也是assert 和if 一起用。

assert只是为了让程序在debug期间尽可能当机已达到release不当机的效果。
当然如果是比较复杂的逻辑,assert也许在debug期间不能跑到所有的情况,这是也就可以assert和if一起用了。

还有就是assert并非出错处理,举个典型的例子就是网络服务器对于非法的消息判断就不能使用assert。总之尽可能使用assert去断言你(程序员)认为是不可能出现的情况。  回复  更多评论
  
# re: 滥用assert 2008-06-16 17:22 yin138
看了作者的文章,以及评论
或多或少的接受到了一些新的见解,呵呵
程序中,使用断言的地方有如下:
1)完全由程序员调用的参数断言,与用户相关最好是同时使用断言各错误处理
2)处理过程中,不应该出错的地方,这个错误是程序员自己编码产生的。
3)在DEBUG编译模式下的可执行文件分离执行时,找到错误的地方。(断言会提供具体断言位置,包括文件,以及行数)  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理