代码契约确保 for 循环未经验证
我刚刚开始尝试 .Net 代码契约(在 VS2010 Ultimate .Net 4 中),试图了解静态检查器可以证明什么和不能证明什么。
我正在尝试以下示例:-
public int Mult(int num1, int num2)
{
Contract.Requires(num2 >= 0);
Contract.Ensures(Contract.Result<int>() == (num1 * num2));
int result = 0;
for (int i = 0; i < num2; i++)
{
result = result + num1;
}
return result;
}
即,通过重复相加来简单实现乘法函数。
静态检查器无法验证是否满足后置条件:-
CodeContracts: ensures unproven: Contract.Result<int>() == (num1 * num2)
我的函数实际上没有正确计算乘积..还是静态检查器无法验证 Requires 的其他原因?循环的存在是否会导致困难?
如果静态检查器在存在循环时很难验证事物,我可以想象一直有很多警告会变得非常烦人。
我不喜欢输入“假设”来告诉它我认为发生了什么,因为通常我的无效假设首先是导致错误的原因!
那么,当静态检查器无法证明某些事情时,我们如何才能帮助它呢? 例如,我可以将该函数重写为递归函数 - 那么检查器是否能够更轻松地验证它? (函数式编程的拥护者可能会说这就是它应该首先编写的方式 - 不改变状态等!)。我还可以通过哪些其他方式更改代码以使静态检查器更容易使用?
谢谢 !:)
I'm just starting to play around with .Net Code Contracts (in VS2010 Ultimate .Net 4), to try to get an idea of what the static checker can and can't prove.
I'm trying to following example :-
public int Mult(int num1, int num2)
{
Contract.Requires(num2 >= 0);
Contract.Ensures(Contract.Result<int>() == (num1 * num2));
int result = 0;
for (int i = 0; i < num2; i++)
{
result = result + num1;
}
return result;
}
ie, a simple implementation of a multiply function, by repeated adding.
The static checker can't verify that the postcondition is met :-
CodeContracts: ensures unproven: Contract.Result<int>() == (num1 * num2)
Is my function not actually computing the product correctly.. or is there another reason why the static checker can't verify the Requires ? Does the presence of a loop cause it difficulty ?
If it's difficult for the static checker to verify things when loops are present, I can imagine it would get quite annoying to have a lot of warnings all the time.
I don't like the option of putting in Assumes to tell it what I think is going on, because it's generally my invalid assumptions that are the cause of bugs in the first place !
So, when the static checker can't prove something, how can we go about helping it ?
For example, I could rewrite the function as a recursive function - would the checker then be able to verify it more easily ? (And advocates of functional programming might say this is how it should be written in the first place - no changing state etc !). What other ways can I change my code to make it easier for the static checker ?
Thanks !:)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
静态检查器永远无法证明这一点,但运行时检查器可以。
静态检查器在编译时应用。为了能够证明你的 Ensures,它必须能够充分分析你的算法和你正在做的事情。它没有那么强大。
当然,每次函数退出时,运行时检查器都会验证 Ensures,并且通过适当的单元测试,这应该证明 Ensures 的有效性。
The static checker will never be able to prove this, but the run-time checker will.
The static checker is applied at compile-time. In order to be able to prove your Ensures, it would have to be able to fully analyze your algorithm and what you're doing. It is not that powerful.
The run-time checker will of course validate the Ensures every time your function exits, and with proper unit-testing, that should prove the validity of the Ensures.