Bad array indexing is considered deadly

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Wed May 31 22:03:17 PDT 2017


On Wednesday, May 31, 2017 23:20:54 Nick Sabalausky  via Digitalmars-d 
wrote:
> On 05/31/2017 10:50 PM, Jonathan M Davis via Digitalmars-d wrote:
> > Yes, there may be cases where array indices are effectively coming from
> > user input, and you're going to have to check them all rather than the
> > code having been written in a way that guarantees that the indices are
> > valid, and in those cases, wrapping an array to do the checks may make
> > sense, but in the vast majority of programs, invalid indices should
> > simply never happen - just like dereferencing a null pointer should
> > simply never happen - and if it does happen, it's a bug.
>
> Yes, it's a bug. A *localized* bug. NOT RAMPANT MEMORY CORRUPTION.

Indexing an array with an invalid index is the same as violating any
contract in D except that you get a RangeError instead of an AssertError,
and the check is always in place in @safe code (even with -release) in order
to avoid memory corruption. As soon as the contract is violated, the program
is in an unknown state. It's logic is clearly wrong, and the assumptions
that it's making may or may not be valid. So, continuing may or may not be
safe.

Whether memory corruption is involved is irrelevant. The program violated
the contract, so the runtime knows that the program is in an invalid state.
The cause of that bug may or may not be localized, but it's a guarantee at
that point that the program is wrong, so you can't rely on it doing the
right thing.

Yes, we _could_ have made it so that the contract of indexing arrays in D
was such that passing an invalid index was considered normal and then have
it throw an Exception to indicate that bad input had been given. But that
means that that code can no longer be nothrow (which does mean that it can't
be optimized as well), and programs would then need to deal with the fact
that indexing an array could throw and handle that case appropriately. For
the vast majority of programs, most array indices do not come from user
input, and thus it usually really doesn't make sense to treat passing an
invalid index to an array as anything other than a bug. It's reasonable to
expect the programmer to get it right and that if they don't, they'll find
it during testing.

If you want to wrap indexing arrays so that you get an Exception, then fine.
At that point, you're saying that it's not a program bug to be passed an
invalid index, and you're writing your programs with the idea that they need
to be able to handle and recover from such bad input. But that is not the
contract that the language itself uses precisely because indexing an array
with an invalid index is usually a bug and not bad program input, and in the
case where the array index _does_ somehow come from user input, then the
programmer can test it. But having the runtime throw an Exception for what
is normally a program bug would harm the programs that actually got their
indices right.

- Jonathan M Davis



More information about the Digitalmars-d mailing list