Given that maintainers of clang and gcc make no effort to handle all of the aliasing corner cases mandated by the Standard (they regard some tricky corner cases they don't handle as being defects in the Standard rather than their compilers), nor to precisely specify what subset of cases they should or should not be expected to handle reliably, I would advise writing code in such a way as to minimize any loss of performance that would result from disabling aliasing, and then documenting a requirement that code be processed with -fno-strict-aliasing
. Otherwise, even if code seems to work today, there would be no way of knowing whether the authors of clang and gcc would will perceive any obligation to avoid having future versions break it.
Note that many of the corner cases where clang and gcc fall down involve things like writing storage with data of a new type whose bit pattern happens to match what was already there. In such cases, clang and gcc are prone to optimize out the write without remembering that the write--as written--changed the Effective Type of the storage in question. To be sure, in most cases where code might write data whose bit pattern matches what the storage already held, clang and gcc wouldn't optimize out the write and lose the change to the Effective Type, but I am unaware of any specification as to when they would be guaranteed not to do so.
Worse, some corner cases involve situations where the fact that code might violate gcc's interpretation of the "Strict Aliasing Rule" if executed is sufficient to cause it to jump the rails, even if the code wouldn't be executed.
For example, given the function:
long test(long *p1, long long *p2, int mode)
{
*p1 = 1;
if (mode)
*(long*)p2 = 2;
else
*p2 = 2;
return *p1;
}
x86-64 gcc 10.2 will generate code that, even if mode
is 1, will ignore the possibility that storing the value 2 to *(long*)p2
might affect the value of p1.