X-Git-Url: https://git.ralfj.de/web.git/blobdiff_plain/47c3cd0d346138c154f853c872464ca22c7ebc74..e806a32d3aa3ce53166c46b8eab5d77a9655c251:/ralf/_posts/2018-07-24-pointers-and-bytes.md diff --git a/ralf/_posts/2018-07-24-pointers-and-bytes.md b/ralf/_posts/2018-07-24-pointers-and-bytes.md index 68a2cb0..636fa40 100644 --- a/ralf/_posts/2018-07-24-pointers-and-bytes.md +++ b/ralf/_posts/2018-07-24-pointers-and-bytes.md @@ -32,13 +32,18 @@ int test() { } {% endhighlight %} It would be beneficial to be able to optimize the final read of `y[0]` to just return `42`. +C++ compilers regularly perform such optimizations as they are crucial for generating high-quality assembly.[^perf] The justification for this optimization is that writing to `x_ptr`, which points into `x`, cannot change `y`. +[^perf]: To be fair, the are *claimed* to be crucial for generating high-quality assembly. The claim sounds plausible to me, but unfortunately, I do not know of a systematic study exploring the performance benefits of such optimizations. + However, given how low-level a language C++ is, we can actually break this assumption by setting `i` to `y-x`. Since `&x[i]` is the same as `x+i`, this means we are actually writing `23` to `&y[0]`. Of course, that does not stop C++ compilers from doing these optimizations. -To allow this, the standard declares our code to have [undefined behavior]({% post_url 2017-07-14-undefined-behavior %}). +To allow this, the standard declares our code to have [undefined behavior]({% post_url 2017-07-14-undefined-behavior %}).[^0] + +[^0]: An argument could be made that compilers should just not do such optimizations to make the programming model simpler. This is a discussion worth having, but the point of this post is not to explore this trade-off, it is to explore the consequences of the choices made in C++. First of all, it is not allowed to perform pointer arithmetic (like `&x[i]` does) that goes [beyond either end of the array it started in](https://timsong-cpp.github.io/cppwp/n4140/expr.add#5). Our program violates this rule: `x[i]` is outside of `x`, so this is undefined behavior.