Incrementing Vectors (2019)
travisdowns.github.io
travisdowns.github.io
void vector8_inc(std::vector<uint8_t> &v) { for (uint8_t &x : v) { ++x; } }
No need to deal with indices or pointers, no obfuscated code, no additional variables, only one clearly stated side effect (we don't need to update a local variable), reads like simple English. I personally don't like C++ (I prefer C) but why would you write C like code in C++?
This article isn't really meant to highlight something problematic about vectors in particular, but with C and C++ in general: that we actually rely on aliasing-based optimization in many cases and this optimization is fragile.
The basic operation here is simply indexing into an array stored in a struct which is quite common, even though you of course should prefer the range-based for this minimal example.
"What about the range-based for loop introduced in C++11?
Good news! It works fine. It is syntactic sugar for almost exactly the iterator-based version above, with the end pointer captured once before the loop, and so it performs equivalently."
It's unfortunate, because what is likely an obscure case (where the user of the function call intends to alias things in the very container they are using) is a minority use case but it ruins the situation for most other code.
Repro. As the other commenter said, the internal data pointers need to be of unknown provenance (e.g. non-local).
Besides the lacking optimization due to aliasing, could there also be some microcode iffyness be going on? Can an x86/64 cpu just increment an 1 byte value positioned at a random memory location?
But the general problem (writing to a char* of unknown provenance might force the compiler to reload any other pointer reads) remains, of course.