简体   繁体   中英

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM