I think the specification allows arbitrary conversions of pointer types to void* according to the third bullet point in the assignability checklist. This means that e.g.
t* is convertible to
void*, as long as t is allowed to be “pointed to”, i.e.
void*. However what if I have
int**? I consulted an online C compiler and it threw an error, so I would assume it is invalid. (First google result is always right)
I am not sure why it is okay for
void* to do sketchy things but not
void* is a crude form of polymorphism. You can convert it to any other pointer and convert to it from any other pointer.
Now, convertability is not a congruence. Just because you can convert from
char does not mean you can convert from
char*. In fact, these types have different alignment requirements, offsetting addition scales by different amounts, etc.
In order for such a rule to be sound, you would need to at least have the same size and alignment requirements on the types. Further, it might be a useful feature that unsafe casts are written down explicitly. If you can convert
void* are laid out equally in memory, you could bypass that.
void** is a pointer to a pointer type, so you might guess that you can convert the pointed-to type to any other pointed-to type it is convertible to. But for reasons explained above, you can’t. So your pointer to an arbitrary pointer is not convertible to a pointer to a more specific pointer because that’s what the rules we are stuck with say.
So in general, the answer is that coming up with working, useful typing rules that allow your conversion and are general enough to be useful is non-trivial, so the C creators side-stepped it.