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).