The cast is necessary as what you do is a form of type punning: You reinterpret the memory which is pointed to from char *
to void *
.
For these types, the C standard guarantees that this actually works as char *
and void *
have the same representation. For other type combinations, this may not be the case.
The relevant parts of the standard are section 6.2.5, §27
A pointer to void shall have the same
representation and alignment
requirements as a pointer to a
character type. Similarly, pointers
to qualified or unqualified versions
of compatible types shall have the
same representation and alignment
requirements. All pointers to
structure types shall have the same
representation and alignment
requirements as each other. All
pointers to union types shall have the
same representation and alignment
requirements as each other. Pointers
to other types need not have the same
representation or alignment
requirements.
and less relevant (but perhaps also interesting) section 6.3.2.3, §7
A pointer to an object or incomplete
type may be converted to a pointer to
a different object or incomplete type.
If the resulting pointer is not
correctly aligned for the pointed-to
type, the behavior is undefined.
Otherwise, when converted back again,
the result shall compare equal to the
original pointer. When a pointer to an
object is converted to a pointer to a
character type, the result points to
the lowest addressed byte of the
object. Successive increments of the
result, up to the size of the object,
yield pointers to the remaining bytes
of the object.
Anything beyond that is implementation-specific.