Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

>The reason for that is that C does not offer a generic function pointer type, and standard C disallows casts between function pointer types and object pointer types.

I've wondered why this hasn't been relaxed a bit when void* is used. Say you have these functions (modified from the link)

  int compare (const char *a, const char *b) {
          return strcmp(a, b);
  }
  
  int compare (const void *a1, const void *b1) {
          const char *a = a1;
          const char *b = b1;
          return strcmp (a, b);
  }
And then you have some FP of type int(*compare)(const void *a1, const void *b1) somewhere...

If you have correct pointer const-ness, why isn't the first method the PREFERRED way of doing this? It's shorter, more clear, safer (calling compare directly and not through a FP still gets you proper type checking (you wouldn't call either of these example functions directly, but for others you might)), and IDE suggestions can better explain what the function is. I've thought several times about suggesting to compiler writers/the C committee to bless the first method. Is there some obscure hardware that the first would be incorrectly compiled or something (i.e. the calling convention for void* and foo* is different)?



C11:

    A pointer to void shall have the same representation and alignment requirements as a pointer to a character type. [48]
    <blah blah pointers to qualified vs unqualified, structs, and unions also have the same representation between themselves>.
    Pointers to other types need not have the same representation or alignment requirements.
    
    [48]: The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.
The thing I've heard for systems where e.g. an int* and char* aren't equal is where the "int*" is the "primary" pointer type, and a char* has to add back the would-be-leading-bits or something. Though as per the above quote, char* vs void* would be safe? Doesn't help anything other than char* though.


There used to be hardware that supported pointers to individual bits or complete words, rather than the eight-bit bytes we see today.

https://en.wikipedia.org/wiki/Word_addressing


I am not sure I understand what you say (despite having read your message several times), but pointers don't have all the same size. Not always, at least. (void* is supposedly big enough to contain any type of pointer, even if I think I remember I read that it's not necessarily true for function pointers).

And if the size of "void" and "char" aren't the same you cannot push two void* on the stack and pop two char*.

But, like I said: maybe I didn't understood what you said.


I was wondering if pointer size is still a problem. Hopefully this explanation is clearer:

  int compare_char (const char *a, const char *b) {
          return strcmp(a, b);
  }
  
  int compare_void (const void *a1, const void *b1) {
          const char *a = a1;
          const char *b = b1;
          return strcmp (a, b);
  }
  
  int (*call_void)(const void *a1, const void *b1) = &compare_char; //not valid in current C standard
Why can't the standard be changed so that it is valid to set call_void to &compare_char, so we don't need to write the longer compare_void? Are there architectures are still in active use where not all pointers are the same size in plain C (not worrying about C++) that would disallow this?

AFAIK, x86, ARM, MIPS, SPARC, Alpha, and SuperH would all work fine calling compare_char though call_void. There could be some other issues, like near/far on 16-bit x86, but that would be orthogonal to implicit function pointer void* casting, and could still occur if call_void was set to compare_void. Do one of the more obscure embedded CPUs still in use have a varying pointer size?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: