Can anyone explain why this is undefined behaviour? UBSan calls it "indirect call of a function through a function pointer of the wrong type" struct foo {int i;}; int func(struct foo *x) {return x->i;} int main() { int (*funcptr)(void*) = (int (*)(void*)) &func; struct foo foo = { 42 }; return funcptr(&foo); } While this is all kosher per the language lawyers: struct foo {int i;}; int func(void *x) {return ((struct f…
> 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 ".