Code Contracts静态分析器不会检测到琐碎的合同违规

时间:2012-12-08 13:04:06

标签: 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<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();
        }
    }
}

在第一次分割通话时,如果我将6替换为0,则静态分析会正确警告。

如果我将6替换为5,那么我(正确地)会在第二次分红呼叫时收到警告。

然而,无论如何,我永远不会在第三个Divide电话上收到任何警告。相反,我只是遇到运行时错误。

为什么静态分析仪无法检测到第三行违反合同?

我在Windows 8 64位上使用Visual Studio 2012。代码合同是Microsoft Code Contracts (devlabs_TS) 1.4.51019.0 for .NET(这似乎是截至2012年12月的最新版本)。

2 个答案:

答案 0 :(得分:3)

我发布了this in the code contracts forum。确认这确实是一个错误,并且它将被修复。

  

错误是静态验证程序认为Divide(3,0 ...)无法访问

     

(...)

     

我们将修复错误。

答案 1 :(得分:1)

这是一个有趣的问题。

我最终将Divide简化为:

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, 10));
    Console.WriteLine(Divide(10, 0));
}

请注意,即使只有一个项目,我发现你必须经常重建而不是构建。必须有代码合同文物在重建时得到清理。

这不会抛出警告:

static void Main(string[] args)
{
    Console.WriteLine(Divide(10, 9));
    Console.WriteLine(Divide(10, 0));
}

我能触发警告的唯一方法是,第一个分界线的分母是10(当它为0时显然也有效)。

这似乎是一个错误 - 我会向代码合同小组发送一封电子邮件,看看他们说了什么。