While answering another question, I thought of the following example:
void *p;
unsigned x = 17;
assert(sizeof(void*) >= sizeof(unsigned));
*(unsigned*)&p = 17; // (1)
memcpy(&p, &x, sizeof(x)); // (2)
Line 1 breaks aliasing rules. Line 2, however, is OK wrt. aliasing rules. The question is: why? Does the compiler have special built-in knowledge about functions such as memcpy, or are there some other rules that make memcpy OK? Is there a way of implementing memcpy-like functions in standard C without breaking the aliasing rules?
The C Standard is quite clear on it. The effective type of the object named by
pisvoid*, because it has a declared type, see6.5/6. The aliasing rules in C99 apply to reads and writes, and the write tovoid*through anunsignedlvalue in(1)is undefined behavior according to6.5/7.In contrast, the
memcpyof(2)is fine, becauseunsigned char*can alias any object (6.5/7). The Standard definesmemcpyat7.21.2/1asHowever if there exist a use of
pafterwards, that might cause undefined behavior depending on the bitpattern. If such a use does not happen, that code is fine in C.According to the C++ Standard, which in my opinion is far from clear on the issue, i think the following holds. Please don’t take this interpretation as the only possible – the vague/incomplete specification leaves a lot of room for speculation.
Line
(1)is problematic because the alignment of&pmight not be ok for theunsignedtype. It changes the type of the object stored inpto beunsigned int. As long as you don’t access that object later on throughp, aliasing rules are not broken, but alignment requirements might still be.Line
(2)however has no alignment problems, and is thus valid, as long as you don’t accesspafterwards as avoid*, which might cause undefined behavior depending on how thevoid*type interprets the stored bitpattern. I don’t think that the type of the object is changed thereby.There is a long GCC Bugreport that also discusses the implications of a write through a pointer that resulted from such a cast and what the difference to placement-new is (people on that list aren’t agreeing what it is).