Patch for range.d to throw when pastLast <= current.
text/plain
447
Comments
Comment #0 by bearophile_hugs — 2010-08-09T07:49:55Z
This generates an 'Access Violation' with dmd 2.048beta:
import std.range;
void main() {
array(iota(1, 0));
}
The expected result of this array() is an empty dynamic array of signed integers.
Comment #1 by kennytm — 2010-08-09T10:40:09Z
If you write
---
import std.range;
import std.stdio;
void main() {
foreach (a; iota(1, 0)) {
writeln(a);
}
}
---
the program will never stop writing. Looks like an integer overflow bug.
Comment #2 by kennytm — 2010-08-09T11:03:43Z
Created attachment 707
Patch for range.d to produce an empty range when pastLast <= current.
This patch produces an empty range when pastLast <= current. But this is inconsistent with the behavior of floating point iota ranges.
Comment #3 by kennytm — 2010-08-09T11:08:17Z
Created attachment 708
Patch for range.d to throw when pastLast <= current.
This patch simply enforces pastLast > current, so it is consistent with the floating point iota range. But it may be less useful.
Comment #4 by dsimcha — 2010-08-19T17:07:09Z
Fixed in changeset 1901. I chose to throw in this case. The proper way to create an empty range would be to do iota(0, 0), or iota(1, 1). The main reason for this choice was consistency with array slicing. For example, if bounds checking is enabled, array[3..2] throws a RangeError.
Comment #5 by bearophile_hugs — 2010-08-19T17:44:23Z
Throwing? No, look at Python:
>>> range(1, 0)
[]
It needs to return an empty range.
This:
foreach (i; iota(1, 0))
is the same as:
foreach (i; 1 .. 0)
Or:
for (int i = 1; i < 0; i++)
It's like an empty loop.
Comment #6 by bearophile_hugs — 2010-08-19T17:49:22Z
And by the way, in Python This produces an empty string slice:
>>> "abcdefg"[3:2]
''
Comment #7 by bearophile_hugs — 2010-08-20T05:16:23Z
Thank you for improving this bug. But I reopen the bug because I think raising an error is the wrong design. As I have explained iota() is to be meant as the ranges in for/foreach loops, so iota(1, 0) is like an empty loop, it's not an error.
Comment #8 by bearophile_hugs — 2011-06-29T13:34:52Z
See also bug 6222
Comment #9 by eco — 2012-04-19T18:41:12Z
This now seems to work as you want in DMD 2.059. The following:
import std.stdio, std.range;
void main() {
auto empty_array = array(iota(1, 0));
writeln("type: ", typeof(empty_array).stringof,
", empty? ", empty_array.empty,
", contents: ", empty_array);
}
Outputs:
type: int[], empty? true, contents: []
I'd say it can be closed and marked RESOLVED now.