> The void pointer rules are better in C IMHO as they avoid unneeded casts
...so much this! A void pointer is an "any-pointer" by design. It shouldn't require casting from and to specific pointer types, that defeats the whole point of having void pointers in the first place.
> It shouldn't require casting from and to specific pointer types
You don't need to explicitly cast T* to void* (guaranteed to be safe), you only need to cast when converting out of void*.
The rules are basically the same as casting between pointer-to-derived-class and pointer-to-base-class and they make sense.