The cast is necessary, because what you are doing is a form of pinning like: you reinterpret the memory pointed to by char * to void * .
For these types, the C standard ensures that it really works as char * and void * . For other type combinations, this may not be the case.
The relevant parts of the standard are sections 6.2.5, §27
A pointer to a void should have the same representation and alignment of the requirement as a pointer to the type character. Similarly, pointers to qualified or unskilled versions of compatible types should have the same representation and alignment of requirements. All pointers to structure types must have the same representation and alignment as each other. All pointers to types of unions should have the same presentation and alignment as each other. pointers to other types are not necessarily a representation or alignment requirement.
and less relevant (but possibly interesting), section 6.3.2.3, §7
A pointer to an object or partial type can be converted to a pointer to another object or partial type. If the resulting pointer is not correctly aligned for the directional type, the behavior is undefined. Otherwise, when returning back, the result is compared with the original pointer. When a pointer to an object is converted to a pointer to a character type, the result indicates the smallest address byte of the object. Successive increments of the result, up to the size of the object, indicate pointers to the remaining bytes of the object.
Everything related to implementation,
source share