On 06.03.2018 00:52, ag0aep6g wrote:
On 03/05/2018 11:57 PM, Timon Gehr wrote:
On 05.03.2018 22:24, ag0aep6g wrote:
On 03/05/2018 10:11 PM, Walter Bright wrote:
[...]
It is not defined behavior with -boundscheck=off.


Dereferencing null is not defined with -boundscheck=off?

This was my bad. It's not dereferencing null. The compiler is free to assume 0<x.length, which means it is allowed to think that the main function is dead code.

How is it free to assume that?
...

By Walter's definition. -boundscheck=off makes the compiler assume that all array accesses are within bounds. ("off" is a misleading term.)

This was the full snippet (before I mutilated it in my quote):

----
void main()@safe{
      int[] x=[];
      writeln(x[0]); // range violation even with -release
                     // defined behavior even with -boundscheck=off (!)
}
----

There is no `assert(0<x.length);` in this one. -release doesn't do anything, because there are no contracts, no asserts, and main is @safe. -boundscheck=off just makes it so that the length isn't checked before x.ptr is dereferenced.

It's not checked, but the compiler may still assume that it has actually been checked. The story is similar to asserts.

x.ptr is null, so the code is defined to dereference null, no?

If -boundscheck=off somehow does introduce UB here, we have the weird situation that using `x.ptr[0]` is more safe than in this scenario than `x[0]`. Because surely `x.ptr[0]` is a null dereference that's not affected by -boundscheck=off, right?

Yes, I think that's a good point (though it hinges on the assumption that x.ptr[i] is equivalent to *(x.ptr+i), which I'm not sure the specification states explicitly).

Reply via email to