社区
C++ 语言
帖子详情
throw和 assert
Soundboy
2004-07-14 02:13:26
究竟什么时候应该用throw,什么时候应该用asert
谁能给个比较完整的原则。
...全文
594
33
打赏
收藏
throw和 assert
究竟什么时候应该用throw,什么时候应该用asert 谁能给个比较完整的原则。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用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)
assert
-exception:断言异常功能(抛出拒绝)
throw
new Error ( 'foo' ) ; } , ( error ) => {
assert
( error . message === 'foo' ) ; return true ; // requirement :( } ) ; // pass 具有
assert
-exception import
assert
from 'power-
assert
' ; ...
browser-
assert
:轻量级断言模块
用于浏览器和旨在与一起使用的Featherwight
assert
功能。 function
assert
( expr , message ) { if ( ! Boolean ( expr ) ) {
throw
new Error ( message || 'unknown
assert
ion error' ) ; } } 安装 npm i ...
koopashell:复杂的外壳测试框架:trade_mark:
库巴壳 复杂的外壳测试框架:trade_mark: 红色还是绿色?用法koopashell [
assert
name] value deepEqual是默认
assert
name 。 参考: : koopashell 将使用
assert
name函数将 stdin 输入与...87
throw
new
assert
.
Assert
io
terraform-provider-
assert
:Terraform提供程序提供类似断言的功能
= "default" // must return TRUE or FALSE
throw
= "default workspace is not valid in this project" // must be of type string} 无需使用提供程序“ name” {}块在.tf文件中显式初始化提供程序,只需直接使用...
node-is-mime:检查流或缓冲区是否为有效的mime类型
是哑剧 检查缓冲区,流或文件... { if ( err )
throw
err // simply pass a type and buffer to `checkBuffer` // it will return the type string or null
assert
. ok ( isMime . checkBuffer ( 'image/png' , buffer
C++ 语言
64,662
社区成员
250,515
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章