I recently came across the strict aliasing rule, but I\'m having trouble understanding how to use void *
to perform type punning without breaking the rule.
void *
has nothing to do with type-punning. Its main purposes are:
To allow for generic allocation and freeing operations that don't care about the type of the object the caller is storing there (e.g. malloc
and free
).
To allow a caller to pass a pointer to an arbitrary type through a function that will pass it back via a callback, (e.g. qsort
and pthread_create
). In this case, the compiler cannot enforce type checking; it's your responsibility when writing the caller and callback to ensure that the callback accesses the object with the correct type.
Pointers to void
are also used in a few places (like memcpy
) that actually operate on an object as the overlaid unsigned char []
representation for the object. This could be seen as type-punning, but it's not an aliasing violation because char
types are allowed to alias anything to access its representation. In this case, unsigned char *
would also work, but void *
has the advantage that pointers automatically convert to void *
.
In your example, since the original type is int
and not a union, there is no legal way to type-pun and access it as short
. You could instead copy the value of x
to a union, perform well-defined type-punning there, then copy it back. A good compiler should omit the copy entirely. Alternatively, you could break the write down into char
writes and then it would be legal aliasing.