A void pointer, written void*, holds the address of an object without preserving its type information. Any object pointer can convert to void* and back; converting back to the same type preserves the pointer value. These guarantees apply to object pointers, not function pointers. The address still refers to storage containing an object, but the type information needed to interpret that storage has been discarded. section 12.4
Use void pointers only when a generic interface requires them, and preserve the type-related constraints explicitly:
- Respect target qualification when converting data pointers to and from void pointers. section 18.1.6
- Do not treat void* as a function pointer or use void alone as a variable type. section 12.4
- Recognize that type safety becomes the caller’s responsibility once an interface erases the pointed-to type. section 18.1.6
Generic sorting with qsort
qsort receives an array address as void*, together with the element count, element size, and a comparison function. A comparison function can recover the expected type, as compare_unsigned does by converting its arguments to unsigned const*. The conversion is safe only when the caller’s element type and size agree with the comparator. Returning *A - *B for int values is invalid because the subtraction can overflow; explicit less-than, greater-than, and equality tests avoid that problem. section 11.4
typedef int compar_t(void const*, void const*);
A compact typedef shows the comparison-function interface used with void-pointer-based generic operations. section 18.1.6

