-1

I'm writing a specialized randomizer class and want to ensure it's quality using CodeContracts. A typical randomizer method recieves an upper limit 'max' and returns a positive random value below that limit.

public int Next(int max)
{
    Contract.Requires<ArgumentOutOfRangeException>(0 <= max && max <= int.MaxValue);
    Contract.Ensures(0 <= Contract.Result<int>());
    Contract.Ensures(Contract.Result<int>() < maxValue);

    return (int)(pick() % maxValue);
}

where pick() returns a random UInt32. My question: Why does CodeContracts fail on the last "ensure"?

ChrisWue
  • 18,612
  • 4
  • 58
  • 83
ILa
  • 49
  • 3
  • 1
    Probably because `maxValue != max`. – Daniel Fischer Jan 05 '12 at 17:28
  • If `max==0` your code throws an exception. Your `max` parameter is also badly named, since it doesn't represent the maximal value, but rather the maximal value plus one. – CodesInChaos Jan 05 '12 at 20:05
  • 1
    Your code can't even compile. You have a `max` and a `maxValue` in there. – CodesInChaos Jan 05 '12 at 20:08
  • Is maxValue a global variable? – Kevin Crowell Jan 05 '12 at 20:12
  • @KevinCrowell Even if it's a global variable of type `int` code contracts doesn't complain. – CodesInChaos Jan 05 '12 at 20:15
  • @CodeInChaos I was just trying to figure out if he has defined maxValue somewhere else in the code and the value is lower than max or if this is a copy-paste error. – Kevin Crowell Jan 05 '12 at 20:18
  • Okay, I'm very sory but the maxValue indeed was the same as max. It's a typo on my account. Also, when max==0 might indeed be the problem as it results in division by zero. I'll check that. – ILa Jan 06 '12 at 06:38
  • The problem got fixed thanks to @CodeInChaos. When I specify the contract for max to exceed zero instead of equal or exceed zero and mask the result of pick() % max with 0x7FFFFFFF, cccheck is satisfied. – ILa Jan 06 '12 at 06:55

1 Answers1

2

I cannot reproduce your problem. Code contract doesn't complain about the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.Contracts;

namespace ContractModulo
{
    class Program
    {
        UInt32 Pick()
        {
            return 0;
        }

        public int Next(int max)
        {
            Contract.Requires<ArgumentOutOfRangeException>(0 <= max && max <= int.MaxValue);
            Contract.Ensures(0 <= Contract.Result<int>());
            Contract.Ensures(Contract.Result<int>() < max);

            return (int)(Pick() % max);
        }

        static void Main(string[] args)
        {
        }
    }
}

It doesn't complain either if I keep your maxValue as a separate variable of type int instead of replacing it with max.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262