One of the first results for strict aliasing on google is this article
http://dbp-consulting.com/tutorials/StrictAliasing.html
One interesting thing I noticed is this: h
In this other related question, there is a comment by @DanMoulding. Let me plagiarize it:
The intent of the standard's strict aliasing rules are to allow the compiler to optimize in situations where it doesn't and cannot know whether an object is being aliased. The rules permit the optimizer to not make worst-case aliasing assumptions in those situations. However, when it is clear from the context that an object is being aliased, then the compiler should treat the object as being aliased, no matter what types are being used to access it. Doing otherwise is not in line with the intent of the language's aliasing rules.
In your code, the aliasing of *ptr and acopy is obvious, as both are local variables, so any sane compiler should treat them as aliased. From this point of view the GCC 4.4 behaviour, although in line with a strict reading of the standard, will be considered a bug by most real-world programmers.
You have to consider why there are aliasing rules in the first place. They are so that the compiler may take advantage of optimizations in situations where there might be be aliasing, but most likely there are none. So the language forbids that aliasing and the compiler is free to optimize. For example:
void foo(int *idx, float *data)
{ /* idx and data do not overlap */ }
However, when the aliasing involves local variables, there are no lost optimizations:
void foo()
{
uint32_t x;
uint16_t *p = (uint16_t *)&x; //x and p do overlap!
}
The compiler is trying to do its job as best as possible, not trying to find an UB somewhere to have an excuse to format your hard drive!
There are a lot of code that is technically UB but is ignored by all compilers. For example, what would you think of a compiler that treats this as an empty file:
#ifndef _FOO_H_
#define _FOO_H_
void foo(void);
#endif
Or what about a compiler that ignores this macro:
#define new DEBUG_NEW
simply because the standard allows it to do so?