Weird issue with std.range.iota.length

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Fri Feb 12 00:11:57 PST 2016


On Friday, 12 February 2016 at 05:51:34 UTC, Meta wrote:
> If you try to compile this code, it will currently not work:
>
> foreach (n; iota(1UL, 1000).parallel)
> {
>     //...
> }
>
>
> This is because of how the length is calculated by iota:
>
> auto iota(B, E)(B begin, E end)
> if (isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, 
> E)))
> {
>     import std.conv : unsigned;
>
>     //...
>
>     //The return type of length. When either begin or end
>     //is ulong, then IndexType == ulong
>     alias IndexType = typeof(unsigned(end - begin));
>
>     static struct Result
>     {
>         private Value current, pastLast;
>
>         //...
>
>         @property IndexType length() const
>         {
>             return unsigned(pastLast - current);
>         }
>     }
>
>     return Result(begin, end);
> }
>
>
> And because std.parallelism.TaskPool.defaultWorkUnitSize takes 
> a size_t, which with a 32-bit DMD is uint.
>
> What I want to know is, is this considered a bug? If so I will 
> submit a pull request to fix it.

What it comes down to is that length should always be size_t. 
That's what it is for arrays, and that's what most code expects. 
Allowing other types just causes trouble for generic code. 
However, in the case of iota with long, if length is size_t, then 
on 32-bit systems, it's possible to have a range from iota which 
is longer than size_t can represent (much as it would normally be 
crazy to have a range that long). So, at some point, someone made 
it so that iota uses ulong for length instead of size_t when it's 
a range of longs or ulongs. It's the only thing in Phobos that 
does, and it causes problems. Changing it back to size_t has been 
discussed but not agreed upon. But we're between a rock and a 
hard place with this one. There is no clean solution.

Personally, I'd very much like to see iota just always use size_t 
for length like every other range (the only ranges which would be 
affected would be ludicrously long anyway, and it would only 
affect 32-bit programs). But that hasn't happened yet, so iota 
over longs and ulongs doesn't behave nicely on 32-bit systems.

Regardless of which way we go, the problem will _eventually_ go 
away when 32-bit systems finally die out, but that's likely to 
take a while.

- Jonathan M Davis


More information about the Digitalmars-d mailing list