Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
November 21, 2015 Range violation instead of empty slice on a[3 .. 2] | ||||
---|---|---|---|---|
| ||||
string a = "hello"; string b = a[3 .. 2]; I expect b to become an empty slice, because 3 is >= 2 already after 0 increments, making the slice length 0. Instead, the code throws a range violation. Expressions of this kind come up, e.g., when taking slices near the end of arrays, like "slice = a[b.length .. $];". To make this robust, I need an extra check for b.length > a.length, returning null in this case, otherwise a[b.length .. $]. What's the design reason to prefer throwing over returning an empty slice? -- Simon |
November 21, 2015 Re: Range violation instead of empty slice on a[3 .. 2] | ||||
---|---|---|---|---|
| ||||
Posted in reply to SimonN | On Saturday, 21 November 2015 at 18:03:07 UTC, SimonN wrote:
> string a = "hello";
> string b = a[3 .. 2];
>
> I expect b to become an empty slice, because 3 is >= 2 already after 0 increments, making the slice length 0. Instead, the code throws a range violation.
>
> Expressions of this kind come up, e.g., when taking slices near the end of arrays, like "slice = a[b.length .. $];". To make this robust, I need an extra check for b.length > a.length, returning null in this case, otherwise a[b.length .. $].
>
> What's the design reason to prefer throwing over returning an empty slice?
>
> -- Simon
this is only an error if bounds checking is not turned on. If you compile your example with DMD option "-boundscheck=off", nothing happens, and the slice will be equal (here) to a[3..$];
|
November 21, 2015 Re: Range violation instead of empty slice on a[3 .. 2] | ||||
---|---|---|---|---|
| ||||
Posted in reply to BBaz | On Saturday, 21 November 2015 at 18:28:51 UTC, BBaz wrote:
> this is only an error if bounds checking is not turned on. If you compile your example with DMD option "-boundscheck=off", nothing happens, and the slice will be equal (here) to a[3..$];
Thanks for the hint, I tested this with -boundscheck=off. Then, a[3..2] generates a slice length of (size_t.max), again different from what I might want.
If the reason for this behavior (huge slice length instead of null slice) is performance during disabled bounds checking, then I'm fine with having to make the extra check.
-- Simon
|
November 22, 2015 Re: Range violation instead of empty slice on a[3 .. 2] | ||||
---|---|---|---|---|
| ||||
Posted in reply to SimonN | On Saturday, November 21, 2015 18:03:05 SimonN via Digitalmars-d-learn wrote:
> string a = "hello";
> string b = a[3 .. 2];
>
> I expect b to become an empty slice, because 3 is >= 2 already after 0 increments, making the slice length 0. Instead, the code throws a range violation.
>
> Expressions of this kind come up, e.g., when taking slices near the end of arrays, like "slice = a[b.length .. $];". To make this robust, I need an extra check for b.length > a.length, returning null in this case, otherwise a[b.length .. $].
>
> What's the design reason to prefer throwing over returning an empty slice?
The reason is that you're providing incorrect values. How does the runtime know that you're not just providing it garbage values? D arrays are designed with the requirement that you provide valid indices when indexing or slicing them, and it's considered a logic bug to provide anything other than valid indices in a valid order. If you want your code to use indices that are invalid or which are in an invalid order, then you're going to have to create a wrapper.
- Jonathan M Davis
|
November 22, 2015 Re: Range violation instead of empty slice on a[3 .. 2] | ||||
---|---|---|---|---|
| ||||
Posted in reply to BBaz | On Saturday, November 21, 2015 18:28:49 BBaz via Digitalmars-d-learn wrote:
> this is only an error if bounds checking is not turned on. If you compile your example with DMD option "-boundscheck=off", nothing happens, and the slice will be equal (here) to a[3..$];
It's a logic error regardless. It's just that the runtime won't report it if you turn off bounds checking - just like it won't throw AssertErrors if you turn assertions off. It's not that the error goes away. It's just that runtime stops checking for it. The purpose of turning off the checking is to improve performance at the risk of letting certain errors go uncaught, not to let you not care about such errors. And while it might be the case right now that you get an empty slice with the current implementation when bounds checking is turned off, there is no guarantee that that will be the case in the future. It's undefined behavior.
- Jonathan M Davis
|
November 22, 2015 Re: Range violation instead of empty slice on a[3 .. 2] | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sunday, 22 November 2015 at 00:24:43 UTC, Jonathan M Davis wrote: >> this is only an error if bounds checking is not turned on. > It's a logic error regardless. > you're going to have to create a wrapper. Right, I am using a wrapper, and I'm not relying on any behavior of a[3..2] during -boundscheck=off. > How does the runtime know that you're not just > providing it garbage values? The runtime flags an empty slice as an error here, seemingly without reason, because the slice can't access any element outside of bounds. However, considering (2U - 3U) > 0, I understand that there is no way to catch this problem without comparing the two bounds. And the comparison is designed to be skippable for speed. Therefore, 3..2 is reasonably flagged as an error. So, thanks for pointing it it out again! -- Simon |
Copyright © 1999-2021 by the D Language Foundation