On 14.10.2017 07:20, Jesse Phillips wrote:
On Thursday, 12 October 2017 at 15:37:23 UTC, John Burton wrote:
This is an example of what I mean :-
undefined what it is meant to do anyway, so the compiler can
"optimize" out the if condition as it only affects the case where the
language doesn't define what it's supposed to do anyway, and compiles
the code as if it was :-
void test(int[] data)
{
control_nuclear_reactor();
}
Yeah the C/C++ community/haters love to talk about all the code the
compiler can inject because of undefined behavior. But that is not what
it means.
...
It can mean that, but that is not even what happened in the given example.
The compiler does not know the value of data.length so it could not make
such a transformation of the code.
The compiler can easily prove that the value of data.length does not
change between the two points in the program. According to the
specification, the behavior of the program is undefined in case the
assertion fails, not just the behavior of the program after the
assertion would have failed if it had not been removed.
Now had the assert been written
before the if, you're telling the compiler some properties of
data.length before you check it and it could make such optimizations.
The point is assert tells the compiler something it can use to reason
about its job, not that it can insert additional runtime checks to see
if you code is invalid an then add new jumps to execute whatever the
hell it wants.
In the above example, a branch was removed, not added.
However, optimizers can add branches. (For example, it can check whether
there is aliasing and use optimized code if it is not the case.)
Also, UB can and does sometimes mean that the program can execute
arbitrary code. It's called "arbitrary code execution":
https://en.wikipedia.org/wiki/Arbitrary_code_execution