C23 §6.5.2.2p7
> If the function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function, the behavior is undefined.
Compatible types requires integrating texts from several different paragraphs, but the general notion is "identical type, in a frontend sense", not "same ABI." This means that "const void " and "void " are not compatible types, much less "void " and "struct foo ".
I get that it's defined that way, but I'd really like to know why.
I can see the value in saying that struct x* isn't compatible with struct y*, because they could have different alignment or packing rules. But struct x* and void*, which is already special-cased to allow assignment without a cast? Why aren't these considered compatible in function pointer parameter definitions?
Is there any work involved in casting void* to struct* (on any architecture) that a plain function pointer would miss out?