如果断言失败,是否存在错误?
我一直遵循这样的逻辑:如果断言失败,则存在错误。根本原因可能是:
- 断言本身无效(错误)
- 存在编程错误(错误)
- (没有其他选项)
IE 还有其他结论可以得出吗?是否存在断言失败但没有错误的情况?
I've always followed the logic: if assert fails, then there is a bug. Root cause could either be:
- Assert itself is invalid (bug)
- There is a programming error (bug)
- (no other options)
I.E. Are there any other conclusions one could come to? Are there cases where an assert would fail and there is no bug?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
如果断言失败,则调用者或被调用者中存在错误。不然为什么会有断言呢?
If assert fails there is a bug in either the caller or callee. Why else would there be an assertion?
是的,代码中有一个错误。
代码完成
Yes, there is a bug in the code.
Code Complete
这是个好问题。
我的感觉是,如果断言由于您的代码而失败,那么它就是一个错误。断言是代码的预期行为/结果,因此断言失败将导致代码失败。
That's a good question.
My feeling is, if the assert fails due to your code, then it is a bug. The assertion is an expected behaviour/result of your code, so an assertion failure will be a failure of your code.
仅当断言旨在显示警告条件时 - 在这种情况下,应使用特殊类的断言。
因此,任何断言都应该按照您的建议显示错误。
Only if the assert was meant to show a warning condition - in which case a special class of assert should have been used.
So, any assert should show a bug as you suggest.
如果您使用断言,那么您就遵循了Bertrand Meyer 的契约设计哲学。这是一个编程错误 - 客户端(调用者)没有遵循您指定的合同(断言)。
If you are using assertions you're following Bertrand Meyer's Design by Contract philosophy. It's a programming error - the contract (assertion) you have specified is not being followed by the client (caller).
如果您试图在逻辑上包容所有可能性,请记住,众所周知,电子电路会受到太空辐射的影响。如果正确的光子/粒子在正确的时间击中正确的位置,它可能会导致逻辑上不可能的状态转换。
概率微乎其微,但仍然不为零。
If you are trying to be logically inclusive about all the possibilities, remember that electronic circuitry is known to be affected by radiation from space. If the right photon/particle hits in just the right place at just the right time, it can cause an otherwise logically impossible state transition.
The probability is vanishingly small but still non-zero.
我可以想到一种不会真正归类为错误的情况:
放置一个断言来检查通常应该存在的外部内容。您正在寻找一台机器上发生的异常情况,并且想知道是否是某个特定因素造成的。
一个现实世界的例子(尽管来自断言时代之前):如果某个目录隐藏在某台机器上,程序就会呕吐。我从来没有找到任何应该关心目录是否被隐藏的代码。我对有问题的机器的访问权限非常有限(它上面有一堆会计资料),所以我无法在机器上正确地搜索它,也无法在其他地方重现它。使用该机器执行的某些操作(从未确定罪魁祸首)偶尔会隐藏该目录。
我最终在启动时进行了测试,看看该目录是否被隐藏,如果是,则停止并显示错误。
I can think of one case that wouldn't really class as a bug:
An assert placed to check for something external that normally should be there. You're hunting something nutty that occurs on one machine and you want to know if a certain factor is responsible.
A real world example (although from before the era of asserts): If a certain directory was hidden on a certain machine the program would barf. I never found any piece of code that should have cared if the directory was hidden. I had only very limited access to the offending machine (it had a bunch of accounting stuff on it) so I couldn't hunt it properly on the machine and I couldn't reproduce it elsewhere. Something that was done with that machine (the culprit was never identified) occasionally turned that directory hidden.
I finally resorted to putting a test in the startup to see if the directory was hidden and stopping with an error if it was.
不。断言失败意味着发生了原始程序员不打算或期望发生的事情。
这可能表明:
代码中的错误(您只是错误地调用了该方法)
断言(原始代码)中的错误程序员太热心了,并抱怨你做了一些相当合理的事情,并且该方法实际上可以很好地处理。
已知但未实现的功能。想象一下,我实现了一个可以处理正整数和负整数的方法,但我(目前)只需要它来处理正整数。我知道“完美”的实现可以同时处理这两个问题,但在我真正需要它来处理负数之前,实现支持是浪费精力(而且它会增加代码膨胀并可能减慢我的速度)应用)。所以我考虑过这个案例,但我决定在需求得到证实之前不实施它。因此,我添加了一个断言来标记此未实现的代码。当我稍后通过传入负值触发断言时,我知道现在需要附加功能,因此我必须增强实现。推迟编写代码直到实际需要为止,这样可以节省我很多时间(在大多数情况下,我从不实现附加功能),但是断言可以确保当我尝试使用未实现的功能时不会遇到任何错误。
No. An assertion failure means something happened that the original programmer did not intend or expect to occur.
This can indicate:
A bug in your code (you are simply calling the method incorrectly)
A bug in the Assertion (the original programmer has been too zealous and is complaining about you doing something that is quite reasonable and the method will actually handle perfectly well.
A bug in the called code (a design flaw). That is, the called code provides a contract that does not allow you to do what you need to do. The assertion warns you that you can't do things that way, but the solution is to extend the called method to handle your input.
A known but unimplemented feature. Imagine I implement a method that could process positive and negative integers, but I only need it (for now) to handle positive ones. I know that the "perfect" implementation would handle both, but until I actually need it to handle negatives, it is a waste of effort to implement support (and it would add code bloat and possibly slow down my application). So I have considered the case but I decide not to implement it until the need is proven. I therefore add an assert to mark this unimplemented code. When I later trigger the assert by passing a negative value in, I know that the additional functionality is now needed, so I must augment the implementation. Deferring writing the code until it is actually required thus saves me a lot of time (in most cases I never imeplement the additiona feature), but the assert makes sure that I don't get any bugs when I try to use the unimplemented feature.