Strict aliasing

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(&data32);
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

  • A union
    [js]
    union {
    uint32_t msg;
    unsigned uint16_t asBuffer[2];
    };
    [/js]
  • Disable strict aliasing of the compiler -f[no-]strict-aliasing in gcc
  • Use char*, as char* is an exception to the rule – the specification assumed that char* always aliases other types so you will not fall into the strict aliasing optimisation.
    [js]
    uint16_t *pData16 = reinterpret_cast(reinterpret_cast(&data32));
    [/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

    Leave a Reply

    This site uses Akismet to reduce spam. Learn how your comment data is processed.