Modulo Bug?

bearophile bearophileHUGS at lycos.com
Sun Aug 12 07:59:18 PDT 2012


> It's a localized but important design bug of languages like C 
> that D has carried over for backward compatibility reasons. D % 
> has caused bugs in my code. I suggest to not use the built-in % 
> on numbers that can be negative,

Better to show an example, reduced from a larger program. This
little function has to look for the next true value in a circular
array 'data', before or after a given starting index, according
to a int 'movement' variable that is allowed to be only +1 or -1:


This is Python code, it correctly performs the wrap-around in all
cases:


def find_next(data, index, movement):
      assert movement == 1 or movement == -1
      while True:
          index = (index + movement) % len(data)
          if data[index]:
              break
      return index

#         0      1      2      3      4     5
data = [False, False, False, False, True, False]
print find_next(data, 5, -1) # OK, prints 4
print find_next(data, 0, -1) # OK, prints 4


The D code doesn't work, because of the C %:


size_t findNext(in bool[] data, size_t index, in int movement)
pure nothrow in {
      assert(movement == 1 || movement == -1);
} body {
      do {
          index = (index + movement) % data.length;
      } while (!data[index]);
      return index;
}

void main() {
      import std.stdio;
      //              0      1      2      3      4     5
      const data = [false, false, false, false, true, false];

      writeln(findNext(data, 5, -1)); // OK, prints 4
      writeln(findNext(data, 0, -1)); // not OK
}


Bye,
bearophile


More information about the Digitalmars-d mailing list