Bad array indexing is considered deadly

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Wed May 31 07:07:18 PDT 2017


On 5/31/17 9:54 AM, ketmar wrote:
> Steven Schveighoffer wrote:
>
>> On 5/31/17 9:37 AM, Adam D. Ruppe wrote:
>>> On Wednesday, 31 May 2017 at 13:04:52 UTC, Steven Schveighoffer wrote:
>>>> What are your thoughts? Have you run into this? If so, how did you
>>>> solve it?
>>>
>>> I don't use vibe, but my cgi.d just catches RangeError, kills the
>>> individual connection, and lets the others carry on. Can you do the same
>>> thing?
>>
>> There are a couple issues with this. At least from the perspective of
>> vibe.d attempting to be a mainstream base library.
>>
>> 1. You can mark a function nothrow that throws a RangeError. So the
>> compiler is free to assume the function won't throw and build faster
>> code that won't properly clean up if an Error is thrown.
>>
>> 2. Technically, there is no guarantee by the runtime to unwind the
>> stack. So at some point, your workaround may not even work. And even
>> if it does, things like RAII may not work.
>>
>
> that is, the question reduces to "should out-of-bounds be Error or
> Exception"?

That ship, unfortunately, has sailed. There is no reasonable migration 
path, as every function that uses indexing can currently be marked 
nothrow, and would stop compiling in one way or another. In other words 
mass breakage of every project would likely happen.

> i myself see no easy way to customize this with language attribute
> (new/delete disaster immediately comes to mind). so i'd say: "create
> your own array wrapper/implementation, and hope that all the functions
> you need are rangified, so they'll be able to work with YourArray".

I have, and it seems to work OK for my purposes (and wasn't really that 
bad actually).

Here is complete implementation (should be @safe too):

struct ExArr(T, size_t dim)
{
     T[dim] _value;
     alias _value this;
     ref inout(T) opIndex(size_t idx, string fname = __FILE__, size_t 
linenum = __LINE__) inout
     {
         if(idx >= dim)
             throw new Exception("Index out of bounds", fname, linenum);
         static ref x(ref inout(T[dim]) val, size_t i) @trusted { return 
val.ptr[i]; }
         return x(_value, idx);
     }
}

Now, I just need to search and replace for all the cases where I have a 
static array...

A dynamic array replacement shouldn't be too difficult either. Just need 
to override opIndex and opSlice. Then I can override those in my static 
array implementation as well.

-Steve


More information about the Digitalmars-d mailing list