Thread overview
Bounds check
May 23, 2014
Chris
May 23, 2014
Meta
May 23, 2014
Chris
May 23, 2014
John Colvin
May 23, 2014
bearophile
May 23, 2014
The following:

import std.stdio;

void main() {
  int[5] arg;
  arg[10] = 3;              // Compiler says (of course): Error: array index 10 is out of bounds arg[0 .. 5]
}

import std.stdio;

void main() {
  int[5] arg;
  foreach (i; 0..10) {
    arg[i] = i;
  }
}

Compiler says nothing, but we get a runtime error 'Range violation'.

Bug or design?

May 23, 2014
On Friday, 23 May 2014 at 15:14:47 UTC, Chris wrote:
> The following:
>
> import std.stdio;
>
> void main() {
>   int[5] arg;
>   arg[10] = 3;              // Compiler says (of course): Error: array index 10 is out of bounds arg[0 .. 5]
> }
>
> import std.stdio;
>
> void main() {
>   int[5] arg;
>   foreach (i; 0..10) {
>     arg[i] = i;
>   }
> }
>
> Compiler says nothing, but we get a runtime error 'Range violation'.
>
> Bug or design?

It is design I believe, but it should be possible for the compiler to unroll this loop at compile time and detect the out of bounds access.
May 23, 2014
On Friday, 23 May 2014 at 15:25:37 UTC, Meta wrote:
> On Friday, 23 May 2014 at 15:14:47 UTC, Chris wrote:
>> The following:
>>
>> import std.stdio;
>>
>> void main() {
>>  int[5] arg;
>>  arg[10] = 3;              // Compiler says (of course): Error: array index 10 is out of bounds arg[0 .. 5]
>> }
>>
>> import std.stdio;
>>
>> void main() {
>>  int[5] arg;
>>  foreach (i; 0..10) {
>>    arg[i] = i;
>>  }
>> }
>>
>> Compiler says nothing, but we get a runtime error 'Range violation'.
>>
>> Bug or design?
>
> It is design I believe, but it should be possible for the compiler to unroll this loop at compile time and detect the out of bounds access.

That's what I thought too.
May 23, 2014
On Friday, 23 May 2014 at 15:14:47 UTC, Chris wrote:
> The following:
>
> import std.stdio;
>
> void main() {
>   int[5] arg;
>   arg[10] = 3;              // Compiler says (of course): Error: array index 10 is out of bounds arg[0 .. 5]
> }
>
> import std.stdio;
>
> void main() {
>   int[5] arg;
>   foreach (i; 0..10) {
>     arg[i] = i;
>   }
> }
>
> Compiler says nothing, but we get a runtime error 'Range violation'.
>
> Bug or design?

The language guarantees catching the out-of-bounds at runtime. The compile-time check is merely a courtesy.
May 23, 2014
Chris:

> The following:
>
> import std.stdio;
>
> void main() {
>   int[5] arg;
>   arg[10] = 3;              // Compiler says (of course): Error: array index 10 is out of bounds arg[0 .. 5]
> }
>
> import std.stdio;
>
> void main() {
>   int[5] arg;
>   foreach (i; 0..10) {
>     arg[i] = i;
>   }
> }
>
> Compiler says nothing, but we get a runtime error 'Range violation'.
>
> Bug or design?

Spotting the second bug is beyond the very limited analysis capabilities of the D compiler. But a slightly different but still rather common kind of code (where the index is not mutable) could be spotted as buggy by the compiler:


void main() {
    int[5] data;
    foreach (const i; 0 .. 10)
        data[i] = 0;
    foreach (immutable i; 0 .. 10)
        data[i] = 0;
    int[10] big;
    foreach (const i, x; big)
        data[i] = x;
}

(In D it's very good to tag as const/immutable the indexes of arrays, as work around a design bug of D foreach).

But the compiler must recognize this as correct code:


void main() {
    int[5] data;
    foreach (const i; 0 .. 10)
        if (i < 5)
            data[i] = 0;
}


So can we add this logic in the compiler?

Bye,
bearophile