C# 代码契约静态分析器不会检测到微不足道的契约违反
我有以下代码:C# 代码契约静态分析器不会检测到微不足道的契约违反,c#,static-analysis,code-contracts,C#,Static Analysis,Code Contracts,我有以下代码: using System; using System.Diagnostics.Contracts; namespace TestCodeContracts { class Program { public static int Divide(int numerator, int denominator, out int remainder) { Contract.Requires<ArgumentEx
using System;
using System.Diagnostics.Contracts;
namespace TestCodeContracts
{
class Program
{
public static int Divide(int numerator, int denominator, out int remainder)
{
Contract.Requires<ArgumentException>(denominator != 0);
Contract.Requires<ArgumentException>(numerator != int.MinValue || denominator != -1, "Overflow");
Contract.Ensures(Contract.Result<int>() == numerator / denominator);
Contract.Ensures(Contract.ValueAtReturn<int>(out remainder) == numerator % denominator);
remainder = numerator % denominator;
return numerator / denominator;
}
static void Main(string[] args)
{
int remainder;
Console.WriteLine(Divide(10, 6, out remainder));
Console.WriteLine(Divide(5, remainder, out remainder));
Console.WriteLine(Divide(3, 0, out remainder));
Console.Read();
}
}
}
在第一个Divide调用中,如果我将6替换为0,那么静态分析会正确地发出警告
如果我将6替换为5,则在第二次Divide调用中正确地得到警告
然而,不管怎样,我在第三次通话中从未收到任何警告。相反,我只是得到一个运行时错误
为什么静态分析器无法检测到第三行违反了合同
我使用的是64位Windows 8上的Visual Studio 2012。代码契约是Microsoft code contracts devlabs_TS 1.4.51019.0 for.NET,它似乎是截至2012年12月的最新版本。这是一个有趣的问题 我最终将划分简化为:
public static int Divide(int numerator, int denominator)
{
Contract.Requires<ArgumentException>(denominator != 0);
return numerator / denominator;
}
请注意,我发现即使只有一个项目,您通常也必须重建而不是构建。必须有代码契约人工制品在重建时得到清理
这不会引发警告:
static void Main(string[] args)
{
Console.WriteLine(Divide(10, 9));
Console.WriteLine(Divide(10, 0));
}
我唯一能触发警告的方法是,如果第一个除法的分母是10,那么当它是0时,它显然也起作用
这看起来确实像一个bug——我会给代码合同团队发一封电子邮件,看看他们怎么说。这是一个有趣的问题 我最终将划分简化为:
public static int Divide(int numerator, int denominator)
{
Contract.Requires<ArgumentException>(denominator != 0);
return numerator / denominator;
}
请注意,我发现即使只有一个项目,您通常也必须重建而不是构建。必须有代码契约人工制品在重建时得到清理
这不会引发警告:
static void Main(string[] args)
{
Console.WriteLine(Divide(10, 9));
Console.WriteLine(Divide(10, 0));
}
我唯一能触发警告的方法是,如果第一个除法的分母是10,那么当它是0时,它显然也起作用
这看起来确实像一个bug——我会给代码合同团队发一封电子邮件,看看他们怎么说。我发布了。已经确认这确实是一个bug,并且它将被修复
错误在于静态验证器认为Divide3,0。。。遥不可及
我们将修复这个错误
我贴了。已经确认这确实是一个bug,并且它将被修复
错误在于静态验证器认为Divide3,0。。。遥不可及
我们将修复这个错误
你检查得很彻底吗?中间有重建吗?设置更多的测试调用可能比“将6改为0”更好。@HenkHolterman重建不会改变我的结果。此外,如果我在三个测试函数Test1、Test2和Test3中的第一个Divide调用中分离出我的三个cases6、5和0,然后调用这三个测试函数,我只在其中两个测试函数中得到警告-每个测试函数的第三个Divide调用从未得到警告,尽管这显然违反了合同。你仔细检查了吗?中间有重建吗?设置更多的测试调用可能比“将6改为0”更好。@HenkHolterman重建不会改变我的结果。此外,如果我在三个测试函数Test1、Test2和Test3中的第一个Divide调用中分离出我的三个cases6、5和0,然后调用这三个测试函数,我只在其中两个测试函数中得到警告-每个测试函数的第三个Divide调用从未得到警告,尽管这显然违反了合同,但你说的重建而不是建造是什么意思。你的意思是你必须让它正常工作,还是你必须复制这种行为?我无法为第10、9分区复制此信息-在这种情况下,我仍然得到警告。不管怎样,我都没有发过邮件,但我把它贴在了他们的论坛上——我必须重新构建代码契约才能正常工作。你说的“必须重新构建而不是构建”是什么意思。你的意思是你必须让它正常工作,还是你必须复制这种行为?我无法为第10、9分区复制此信息-在这种情况下,我仍然得到警告。不管怎样,我都没有发过电子邮件,但我把它贴在了他们的论坛上——为了让代码契约正常工作,我不得不重新构建。