C : 为什么可以将 void 函数强制转换为 "pointer to function returning pointer to pointer to void"
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
嗨,C 中的函数指针让我很困惑。第二个定义(简单)非常清楚:我们获取 hello 的地址,并将其放入我们可以使用的函数指针中。
然而,第一个对我来说有点陌生。为什么它有效?如何将指向 void 的 void 函数强制转换为指向返回指向 void 的指针的函数的指针?
编译器如何处理这样的转换?
首先,当函数指示符(包括函数名称,例如 hello
)用于表达式而不是 sizeof
或一元 &
的操作数时,根据 C 2018 6.3.2.1 4,它会自动转换为指向函数的指针。因此,在 void (*simple)() = &hello;
中,不需要 &
; void (*simple)() = hello;
会自动使用函数的地址。这解释了为什么 void *(*gibberish)() = (void *(*)())hello;
.
中不需要 &
其次,强制转换是因为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…
但是,此转换旨在允许将函数指针临时转换为通用类型,以便存储。检索指针时,应在使用它调用函数之前将其转换回适当的类型。第 8 段继续:
… If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.
#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
嗨,C 中的函数指针让我很困惑。第二个定义(简单)非常清楚:我们获取 hello 的地址,并将其放入我们可以使用的函数指针中。
然而,第一个对我来说有点陌生。为什么它有效?如何将指向 void 的 void 函数强制转换为指向返回指向 void 的指针的函数的指针?
编译器如何处理这样的转换?
首先,当函数指示符(包括函数名称,例如 hello
)用于表达式而不是 sizeof
或一元 &
的操作数时,根据 C 2018 6.3.2.1 4,它会自动转换为指向函数的指针。因此,在 void (*simple)() = &hello;
中,不需要 &
; void (*simple)() = hello;
会自动使用函数的地址。这解释了为什么 void *(*gibberish)() = (void *(*)())hello;
.
&
其次,强制转换是因为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…
但是,此转换旨在允许将函数指针临时转换为通用类型,以便存储。检索指针时,应在使用它调用函数之前将其转换回适当的类型。第 8 段继续:
… If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.