这个问题中的代码让我觉得
assert(value>0); //Precondition
if (value>0)
{
//Doit
}
我从来没有写过 if 语句。 断言就足够了/你能做的一切。
“早期崩溃,经常崩溃”
CodeComplete 指出:
- 断言语句使application Correct
- if-test 使应用程序变得健壮
我不认为您通过更正无效的输入值或跳过代码来使应用程序更加健壮:
assert(value >= 0 ); //Precondition
assert(value <= 90); //Precondition
if(value < 0) //Just in case
value = 0;
if (value > 90) //Just in case
value = 90;
//Doit
这些更正基于您对外部世界所做的假设。
只有调用者知道您的函数的“有效输入值”是什么,并且他必须在调用您的函数之前检查其有效性。
解释一下 CodeComplete:
“当我们不仅仅依赖断言时,现实世界的程序就会变得太混乱。”
问:我是不是错了,固执,愚蠢,太不设防了......
The code in this question made me think
assert(value>0); //Precondition
if (value>0)
{
//Doit
}
I never write the if-statement. Asserting is enough/all you can do.
"Crash early, crash often"
CodeComplete states:
- The assert-statement makes the application Correct
- The if-test makes the application Robust
I don't think you've made an application more robust by correcting invalid input values, or skipping code:
assert(value >= 0 ); //Precondition
assert(value <= 90); //Precondition
if(value < 0) //Just in case
value = 0;
if (value > 90) //Just in case
value = 90;
//Doit
These corrections are based on assumptions you made about the outside world.
Only the caller knows what "a valid input value" is for your function, and he must check its validity before he calls your function.
To paraphrase CodeComplete:
"Real-world programs become too messy when we don't rely solely on assertions."
Question: Am I wrong, stuborn, stupid, too non-defensive...
发布评论
评论(9)
如果我没记错的话,CS 类
先决条件定义了函数的输出是在什么条件下定义的。 如果您让函数处理错误条件,则您的函数是为这些条件定义的,并且不需要断言语句。
所以我同意。 通常你不需要两者。
正如 Rik 评论的那样,如果您删除已发布代码中的断言,这可能会导致问题。 通常我不会这样做,除非是在性能关键的地方。
If I remember correctly from CS-class
Preconditions define on what conditions the output of your function is defined. If you make your function handle errorconditions your function is defined for those condition and you don't need the assert statement.
So I agree. Usually you don't need both.
As Rik commented this can cause problems if you remove asserts in released code. Usually I don't do that except in performance-critical places.
我应该声明我知道断言(此处)在生产代码中消失的事实。
如果 if 语句实际上纠正了生产代码中的无效输入数据,则意味着断言在调试代码测试期间从未关闭,这意味着您编写了从未执行过的代码。
对我来说,这是一个 OR 情况:(
引用 Andrew)“防止所有范围的无效输入,我一开始就不会为断言而烦恼。” -> 编写一个 if 测试。
(quote aku) “不正确的输入值是可以原谅的” -> 写一个断言。
我无法忍受两者......
I should have stated I was aware of the fact that asserts (here) dissappear in production code.
If the if-statement actually corrects invalid input data in production code, this means the assert never went off during testing on debug code, this means you wrote code that you never executed.
For me it's an OR situation:
(quote Andrew) "protect against all ranges of invalid input, I wouldn't bother with the assertion in the first place." -> write an if-test.
(quote aku) "incorrect input values can be forgivable" -> write an assert.
I can't stand both...
对于只有您才会使用的内部函数,请仅使用断言。 这些断言将有助于在测试期间捕获错误,但不会影响生产中的性能。
使用if 条件检查源自外部的输入。 从外部来说,这是您/您的团队控制和测试的代码之外的任何地方。
或者,您可以两者都拥有。 这将适用于面向外部的功能,其中集成测试将在生产之前完成。
For internal functions, ones that only you will use, use asserts only. The asserts will help catch bugs during your testing, but won't hamper performance in production.
Check inputs that originate externally with if-conditions. By externally, that's anywhere outside the code that you/your team control and test.
Optionally, you can have both. This would be for external facing functions where integration testing is going to be done before production.
不要忘记大多数语言允许您关闭断言...就我个人而言,如果我准备编写 if 测试来防止所有范围的无效输入,我就不会为断言而烦恼首先。
另一方面,如果您不编写逻辑来处理所有情况(可能是因为尝试并继续使用无效输入是不明智的),那么我将使用断言语句并采用“早期失败”方法。
Don't forget that most languages allow you to turn off assertions... Personally, if I was prepared to write if tests to protect against all ranges of invalid input, I wouldn't bother with the assertion in the first place.
If, on the other hand you don't write logic to handle all cases (possibly because it's not sensible to try and continue with invalid input) then I would be using the assertion statement and going for the "fail early" approach.
断言的一个问题是它们可以(并且通常会)从代码中编译出来,因此您需要添加两堵墙,以防其中一堵墙被编译器丢弃。
A problem with assertions is that they can (and usually will) be compiled out of the code, so you need to add both walls in case one gets thrown away by the compiler.
仅信任断言的问题是它们可能在生产环境中被关闭。 引用维基百科的文章:
因此,如果代码的正确性依赖于断言,您可以运行陷入严重的问题。 当然,如果代码在测试期间有效,那么它也应该在生产期间有效...现在输入第二个负责代码的人,他将解决一个小问题...
The problem with trusting just Asserts, is that they may be turned off in a production environment. To quote the wikipedia article:
So if the correctness of your code relies on the Asserts to be there you may run into serious problems. Sure, if the code worked during testing it should work during production... Now enter the second guy that works on the code and is just going to fix a small problem...
使用断言来验证您控制的输入:私有方法等。
使用 if 语句来验证您无法控制的输入:为用户使用而设计的公共接口、用户输入测试等。
使用内置断言测试您的应用程序。然后在不使用断言的情况下进行部署。
Use assertions for validating input you control: private methods and such.
Use if statements for validating input you don't control: public interfaces designed for consumption by the user, user input testing etc.
Test you application with assertions built in. Then deploy without the assertions.
在某些情况下,在构建发布时会禁用断言。 您可能无法控制这一点(否则,您可以使用断言进行构建),因此这样做可能是一个好主意。
“更正”输入值的问题是调用者不会得到他们期望的结果,这可能会导致程序的完全不同部分出现问题甚至崩溃,使调试成为一场噩梦。
我通常在 if 语句中抛出一个异常,以接管断言的角色,以防它们被禁用
I some cases, asserts are disabled when building for release. You may not have control over this (otherwise, you could build with asserts on), so it might be a good idea to do it like this.
The problem with "correcting" the input values is that the caller will not get what they expect, and this can lead to problems or even crashes in wholly different parts of the program, making debugging a nightmare.
I usually throw an exception in the if-statement to take over the role of the assert in case they are disabled
我不同意这样的说法:
调用者可能认为他知道输入值是正确的。 只有方法作者知道它是如何工作的。 程序员最好的目标就是让客户端掉进“成功的坑里”。 您应该决定在特定情况下哪种行为更合适。 在某些情况下,错误的输入值是可以原谅的,而在其他情况下,您应该抛出异常\返回错误。
至于断言,我会重复其他评论者,断言是代码作者而不是代码客户端的调试时间检查。
I would disagree with this statement:
Caller might think that he know that input value is correct. Only method author knows how it suppose to work. Programmer's best goal is to make client to fall into "pit of success". You should decide what behavior is more appropriate in given case. In some cases incorrect input values can be forgivable, in other you should throw exception\return error.
As for Asserts, I'd repeat other commenters, assert is a debug time check for code author, not code clients.