When slicing a pointer, if one (not both) of the indices is negative, it throws a Range violation. Tested with DMD 2.068.1
example:
auto p = &"aaaaaaaaaaaaaaaaaaaaa"[5];
assert(p[-1] == 'a'); // no problem
assert(p[-3 .. -1] == "aa"); // no problem
assert(p[-1 .. 1] == "aa"); // 'Range violation'
( http://dpaste.dzfl.pl/3be7eb85483c )
Comment #1 by dlang-bugzilla — 2015-09-28T09:01:28Z
> assert(p[-1 .. 1] == "aa"); // 'Range violation'
What happens here is that -1 gets implicitly casted to size_t, which is unsigned, so this becomes p[size_t.max .. 1]. Slicing p[a..b] when a>b is nonsense, hence the RangeError.
The check is removed when -release is present.
I'm not sure this is a bug.
Comment #2 by cauterite — 2015-10-01T10:10:05Z
Hmm yes, it seems all operations with array indices are treated as unsigned, and just happen to do the right thing in most cases because the integers are modular (e.g. adding size_t.max is the same as subtracting 1).
I propose instead of silently casting signed values to unsigned, the compiler should explicitly disallow use of signed values as array indices (or at least emit a warning, so as to not break existing code).
(In reply to Vladimir Panteleev from comment #1)
> > assert(p[-1 .. 1] == "aa"); // 'Range violation'
>
> What happens here is that -1 gets implicitly casted to size_t, which is
> unsigned, so this becomes p[size_t.max .. 1]. Slicing p[a..b] when a>b is
> nonsense, hence the RangeError.
>
> The check is removed when -release is present.
>
> I'm not sure this is a bug.
Comment #3 by b2.temp — 2018-12-06T19:25:05Z
The warning would only work for literals and CTFE-ed IntExp so i don't think this is very useful
Comment #4 by dlang-bugzilla — 2018-12-06T19:26:58Z
(In reply to Basile B. from comment #3)
> The warning would only work for literals and CTFE-ed IntExp so i don't think
> this is very useful
It would be useful because negative indexes are used in some languages to indicate an offset from the end of the string.
Comment #5 by dfj1esp02 — 2018-12-07T08:39:39Z
The example uses negative index to indicate offset from the beginning of the string, not from the end. Pointers have no notion of the end of the string anyway.
Comment #6 by robert.schadek — 2024-12-13T18:44:42Z