for ranges

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jan 22 09:10:28 PST 2015


On 1/22/15 11:41 AM, Russel Winder via Digitalmars-d-learn wrote:
> Playing with factorial implementations, as you do. I had a D
> implementation using ulong. Not sensible obviously since overflow is a
> bit of a problem. But the code worked, as did the tests. Now converting
> to BigInt and…
>
> The standard explicit iteration form uses a loop:
>
> 	for(i; 2..n+1)
>
> for n = 0 or 1 this loop doesn't loop since the range is [,). However
> for BigInt:
>
> 	for(i; two..n + one)
>
> the loop starts at 0 and just keeps on going. This is clearly not good.
>
> Am I having a mental breakdown or is this a real bug?
>
>

The issue:

import std.stdio;

struct S
{
     int x;
     int opCmp(const S other) const { writeln("compare"); return x < 
other.x ? -1 : x > other.x ? 1 : 0;}
     bool opEquals(const S other) const { writeln("equals"); return x == 
other.x;}
     ref S opOpAssign(string op)(int other)
     {
         mixin("x " ~ op ~ "= other;");
         return this;
     }
}

void main()
{
     immutable S one = S(1);
     immutable S two = S(2);
     foreach(s; one..two) {}
}

output:
equals
equals

So foreach(S; one..two) translates to:

for(S x = one; x != two; x += 1)

which explains the infinite loop. I'm almost positive foreach(x; 1..2) 
uses comparison instead of equality to check for end condition.

-Steve


More information about the Digitalmars-d-learn mailing list