#include <stdio.h>
void hello() {
printf("hello world\n");
}
int main() {
void *(*gibberish)() = (void *(*)())hello;
(*gibberish)();
void (*simple)() = &hello;
(*simple)();
return 0;
}
$ cc pt_func.c && ./a.out
hello world
hello world
Hi, pointers to function in c confuse me. The second definition (simple) is quite clear : we take the adress of hello, and put it in a pointer to function that we can use.
However, the first one is a bit strange to me. Why does it work ? How a void function to void can be cast to a pointer to function returning pointer to void ?
What does the compiler do with such a cast ?
CodePudding user response:
First, when a function designator (which includes a function name such as hello
) is used in an expression other than as the operand of sizeof
or of unary &
, it is automatically converted to a pointer to the function, per C 2018 6.3.2.1 4. So, in void (*simple)() = &hello;
, the &
is not needed; void (*simple)() = hello;
will automatically use the address of the function. This explains why no &
is needed in void *(*gibberish)() = (void *(*)())hello;
.
Second, the cast is defined because C 6.3.2.3 8 says
A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer…
However, this conversion is intended to allow temporary conversion of a function pointer to a common type so it can be stored. When the pointer is retrieved, it should be converted back to an appropriate type before using it to call the function. Paragraph 8 continues:
… If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.