'C : why is that cast of void function to "pointer to function returning pointer to pointer to void" possible

#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 ?



Solution 1:[1]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Eric Postpischil