Comment by jcranmer

5 months ago

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?

  • Yes, some restrictions seem arbitrary. Just like why these two types are not compatible:

      struct a {int data;};
      struct b {int data;};
    

    I know, I know, changing it would break existing code, etc.

    • You jest, but a central feature of C is that void* is a universal pointer, and can be used as the basis of polymorphism and context passing. That's why you can do things like:

          void qsort(void *base, size_t nmemb, size_t size,
                     int (*compar)(const void *, const void *));
      

      It would be nice to write:

          int compare_foo(const struct foo *a, const struct foo *b) {
              ...
          }
      

      But instead we have to write this to avoid being declared "undefined behaviour":

          int compare_foo(const void *a, const void *b) {
              const struct foo *real_a = (struct foo *)a;
              const struct foo *real_b = (struct foo *)b;
              ...
          }
      

      So what is the upside of having this rule, given the same thing is going to happen anyway, just more verbose?