throw和 assert

Soundboy 2004-07-14 02:13:26
究竟什么时候应该用throw,什么时候应该用asert

谁能给个比较完整的原则。
...全文
594 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
Soundboy 2004-08-04
  • 打赏
  • 举报
回复
好,结贴了,这个分没有白扔。
Wolf0403 2004-07-29
  • 打赏
  • 举报
回复
C++ 的异常代价太大,而且通常也不必使用……根据所用的库的习惯来决定吧。
应该养成使用 assert 的习惯。
changeme 2004-07-29
  • 打赏
  • 举报
回复
throw需要消耗系统资源,但是assert不需要。
所以,在效率第一的情况下,不使用throw,只对一些致命的错误,如数组下标越界检查时,使用assert。

bluejugar 2004-07-29
  • 打赏
  • 举报
回复
什么时候用throw,什么时候用assert,2004年7月下期的<<开发高手>>里付仲恺的文章讲得挺好.
我给你摘下相关的这一条:

异常使用原则:(p108)
在讨论过异常的基本使用方法后, 再来讨论一个十分重要的问题,就是什么时候使用异常.在这里我们将使用"契约"理论进行分析.
这里据说的契约与生活中的契约十分相似,它主要包含以下两条规则:
1.契约关系是双方(多方)在平等的基础上建立的.对契约所涉及到的整个程序而言,任何一方在拥有相应的权利的同时,也必须承担相应的义务.权利和义务是相互统一的.
2.对于双方,甲所执行的契约的结果由乙来审核,同样乙所完成的契约由甲来审核.
契约理论认为, 一个程序之所以能正常运行,其关键在于程序的各个部分都完全履行了自己的契约.而程序之所以会出现错误.其原因就在于程序中存在着没有按照要求履行契约的模块.那么是不是程序中发生的所有错误都应当由异常来承担呢?显然不是.
(手有点酸了,休息下.)

在这里这我先给出在契约理论下,使用异常处理情况的解释.即"在乙方完全履行了契约后,甲方使乙方的结果,仍然不能完成信息任务时,甲方应该发出异常".这就是说,当问题是由于甲方自身造成的与乙方无关,且甲方无力解决问题的时候,应该抛出异常.
那么这与我们谈到什么时候该用异常有什么关系?当然有关系.为了能更好的理解使用异常的环境,举例如下:
doit()
{
...
proc(dest,src);
...
}
proc(char* dest,char* src)
{
if(dest == NULL)
{...}
...
}
当dest为NULL时,是否应该抛出异常呢?
根据前面所说的规则2,这里的代码表明proc函数正在审核doit函数是否履行了契约,即proc函数正在使用契约中它自己的权利.当proc函数发射dest为NULL时,proc函数就可以认为doit函数没有履行它应尽的义务.根据前面对使用异常情况的定义,由于错误是由doit函数选成的,与proc函数无关.因此,proc函数不应该抛出异常,它应该做的是终止契约,返回doit函数并告诉它,"dest"有问题你自己着办吧."然后由doit函数决定下一步的操作.
事实上,这条判断语句应该使用断言(assert).在实际开发中,往往有些开发者会将本来应该使用断言处理的事情都交给了异常,这显然是一种不妥的做法.那么什么情况下应该使用断言呢?通过上面的例子可以看到,对于那些可能通过修改程序而得到纠正的错误,就应该使用断言.
Soundboy 2004-07-20
  • 打赏
  • 举报
回复
??
vcchunhong 2004-07-20
  • 打赏
  • 举报
回复
try
{
..........
throw(...);
}

后面接的应该是
catch(.....)
{
}

//////////////////////
asert
我还没见过

jiang8360 2004-07-20
  • 打赏
  • 举报
回复
学习
Soundboy 2004-07-19
  • 打赏
  • 举报
回复
gui00(东青木) :

怎么不能拿这两者来比较,都是出问题时候用的东东。很多初学者(包括我曾经)都是不使用的。
-----------------------------------------
另:

如果字符串溢出,应该用什么呢?为什么呢?
gui00 2004-07-18
  • 打赏
  • 举报
回复
assert是调试定位用的(Debug版本);
抛出异常是处理出错时可以使用的一招,用以通知上层调用者调用出现了问题;不明白怎么拿这二者来比较。
yndfcd 2004-07-17
  • 打赏
  • 举报
回复
assert用于检查某个条件是否成立,如果不成立则说明程序肯定有问题.是什么问题,是无法得知的.

而throw是在发生可预知的错误时,将错误信息传递给使用者,以便可以处理.

用法如

1.assert
void InsertElement( ElementType** array, int pos, ElementType* ele )
{
assert( array[ pos ] == NULL ); //确保原来的地方为空
//如果不为空,说明程序的某个地方有错
array[ pos ] = ele;
}


2. throw
float Divide( int x, int y)
{
if ( y == 0 )//错误是可以预知的
throw zero_divid_exception();
return x/y;
}
leebuilder 2004-07-17
  • 打赏
  • 举报
回复
assert用于调用函数时候,函数中判断参数是否有效时候用的
throw用于程序出现异常状况的时候
wasoxi 2004-07-16
  • 打赏
  • 举报
回复
你还不明白吗?
Soundboy 2004-07-16
  • 打赏
  • 举报
回复
不错,不错,问题愈辩愈明。

再等待精彩论点,不日结贴。
rtdb 2004-07-16
  • 打赏
  • 举报
回复
同意 rorot(喵喵喵。。。[无聊啊]。。。。。。。。) 的说法。
assert()是给程序员用的。

这个程序员,一是指编程者自己,
二也是指其它要使用这段程序的程序员。

所以,只有基于程序员的错误才应用assert。
比如说传进来一个错误的参数等。

至于资源不足之类的问题,就用throw()扔给用户。

换个角度说,
用户能处理的问题用throw(),
用户不能处理的问题用assert()。



Jinhao 2004-07-16
  • 打赏
  • 举报
回复
由运行期导致的异常就用 throw
gooddayboy 2004-07-16
  • 打赏
  • 举报
回复
我也明白了
Wolf0403 2004-07-14
  • 打赏
  • 举报
回复
当你确信某个地方某个条件应该成立的时候,用 assert 检查。

size_t strlen (const char * str)
{
// 我们确信传入的不是一个空指针,所以用
assert (str != NULL);
// ...
}

这里 str != NULL 属于 pre-condition,有时候还会出现 post-condition,也可以用 assert 检查。

当定义了 NDEBUG 宏的时候(譬如 VC 中的所谓 Release 版本),assert 被定义成空语句,所以不影响效率。如果没有定义 NDEBUG 宏,则 assert 会检查参数;如果条件参数不成立,assert 会打印一条错误消息报告出错的地方,然后调用 abort 退出程序。

无聊啊~
munn 2004-07-14
  • 打赏
  • 举报
回复
assert打印错误信息而已
freefalcon 2004-07-14
  • 打赏
  • 举报
回复 1
没有定论的,个人喜好和习惯起很大作用
一个最大的区别是
assert的条件为假时,程序便会abort终止
throw抛出的异常如果被catch住,程序还能正常运行

所以:
对于一些显而易见的错误,比如一个不能为NULL的指针参数被赋值为NULL,那么用assert也许合适些,这样可以让错误在程序在测试的时候就能发现,方便程序员调试

另外对于一些不应该出现的状态或者情形,也可以直接用assert弹出信息告诉程序员
如assert(!"invalid parameter");

其他的,真的就看个人风格,如果你是唯c++者,你可以到处都用异常,如果不喜欢,你可能根本不用c++异常
rorot 2004-07-14
  • 打赏
  • 举报
回复
当我作程序的debug版本时,为了扑捉自己能够杀死的臭虫,
往往在某些地方assert(scanlar expression)
当有bugs时,它可以给我打印出信息告诉我臭虫在那儿,并调用abort()来中止程序
当然,这里的assert()是给我自己用的.
这里: assert()的使用者考虑的是程序员自己...

当我作一些程序或者自己的库给别人用的时候,我知道程序里可能有bugs,
但是我不知道这样的bugs在以后别人使用我这套代码时会发生多么严重的问题...
因为这个bugs不影响我,而影响的是这个程序的使用者(user)..客户...
所以我只能throw(),出去,告诉它这里有异常,至于怎么处理,我管不着...
这里throw()考虑的是客户..user...
加载更多回复(13)

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧