Originally Posted by
Yarin
Nope.
If you go by C89 or C99 rules (I haven't checked C11), you cannot cast function pointers to object pointers or vice versa. Furthermore, strchr and &strchr are the exact same thing; function pointers are funky in C.
In other words, ISO C forbids
Code:
void *p;
p = strcmp;
p = &strcmp;
but only because it does not allow you to assign a function pointer to an object pointer. The workaround is simple:
Code:
void *p;
*(int (**)(const char *, const char *))&p = strcmp;
Note that above, int is the function result type, and the const char *, const char * are the parameters the function takes. The ** means we have a pointer to a pointer to such a function. In other words, we take the address of the variable, cast it to an address to a function pointer, and then dereference and assign.
When using a function such as dlsym() which returns a pointer to a function as a void pointer, you need to use
Code:
int (*func)(const char *, const char *);
*(void **)&func = dlsym(NULL, "strcmp");
which is basically the reverse. We take the address of a function pointer variable, cast that to a pointer to a void pointer, dereference, and assign.
To correctly print the address of a function, you need to use a temporary void pointer. For example,
Code:
*(int (**)(const char *, const char *))&p = strcmp;
printf("The address of strcmp is %p\n", p);
*(int (**)(const char *, const char *))&p = &strcmp;
printf("The address of strcmp is %p\n", p);
Both do the same thing. I prefer the first one, because it keeps the funkyness of the function pointers fresh in my mind; I've found it works for me best.
The reason for this mess is that there are architectures where function pointers are not standard pointers, and may require special handling from the compiler. The above workaround patterns were actually suggested by the C standard developers, so if you happen to run code on such a rare architecture, the above code should work there just fine, whereas the typical "I don't care about those stupid warnings, this works on my machine" code tends to fail in spectacular ways.