preamble
Strict aliasing was introduced in C++98, but can be a gotcha. Strict pointer aliasing is allowed by the C++ standard, and is where the compiler is allowed to decide two pointers don’t point at the same object if they’re of unrelated types. e.g.
[js]
uint32_t data32;
uint16_t *pData16 = reinterpret_cast
uint16_t first = pData16[0];
uint16_t second = pData16[1];
[/js]
Here ‘first’ and ‘second’ may not point to what you expect.
Discussion
The compiler is at liberty to assume pointers to different types will not affect one another, in order to allow for more efficient code generation.
The solution to the above code is to to either use
[js]
union {
uint32_t msg;
unsigned uint16_t asBuffer[2];
};
[/js]
[js]
uint16_t *pData16 = reinterpret_cast
[/js]
However adding a comment to the code for this will definitely be necessary as someone may remove you char* cast if they don’t know the rules.
Epilog
After stating the above it must be noted that most likely the example given in the ‘preamble’ will work! It is however in undefined behaviour territory. GCC around 3.x seems to follow strict aliasing rules and you will probably not get what you expect, but later versions seem to follow the coders intent. I however have been testing on ‘clang’ and it appears not to generate any aliasing warning outputs.
My feeling are now in 2018, you probably will get away with this bad code, or pick it up in debugging, but undefined behaviour is still undefined behaviour, and best to be avoided. I think this issue came more to the front due to gcc 3.x, following the letter of the law (c++ standard) rather than the programmer’s intent. I am not condoning writing non-compliant code!
Reference
https://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule
http://en.cppreference.com/w/cpp/language/reinterpret_cast
https://stackoverflow.com/questions/34527729/why-compilers-no-longer-optimize-this-ub-with-strict-aliasing