Weird issue with std.range.iota.length

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Fri Feb 12 07:59:09 PST 2016


On Friday, 12 February 2016 at 14:36:29 UTC, Meta wrote:
> On Friday, 12 February 2016 at 08:11:57 UTC, Jonathan M Davis 
> wrote:
>> 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
>
> What about adding another overload of iota, say, iotaEx or 
> something along those lines. All it would do is the following:
>
> auto iotaEx(B, E)(B begin, E end)
> {
>     assert(unsigned(end - begin) <= size_t.max);
>
>     static struct Result
>     {
>         typeof(iota(begin, end)) payload;
>
>         @property size_t length()
>         {
>             return cast(size_t)payload.length;
>         }
>
>         alias payload this;
>     }
>
>     return Result(iota(begin, end));
> }

It would be far better IMHO to just do a check in iota and throw 
a RangeError if the length wouldn't fit in size_t. Having length 
ever be anything other than size_t is just going to cause 
problems with other ranges. On 32-bit systems, you lose out on 
the ability to have a range that covers all values of long or 
ulong, but that's of very limited usefulness anyway, and as long 
as the number of elements is no greater than size_t.max, it would 
be fine - which would cover virtually all use cases. No, it's not 
perfect, but allowing length to be anything but size_t just 
causes bugs - especially in generic code.

- Jonathan M Davis


More information about the Digitalmars-d mailing list