void*被定义为可以指向任何东西,那么它能否用来指向一个函数(比如int send())?
int send();
void* p = send;
这是可能的吗?当我像这样使用时,它没有显示错误,为什么?如果不行,有没有办法将所有指针存储在一个变量中?
void*被定义为可以指向任何东西,那么它能否用来指向一个函数(比如int send())?
int send();
void* p = send;
这是可能的吗?当我像这样使用时,它没有显示错误,为什么?如果不行,有没有办法将所有指针存储在一个变量中?
将函数指针转换为对象指针类型或反之亦然是有条件支持的。这种转换的含义是实现定义的,除非一个实现同时支持两个方向的转换, 将一个类型的prvalue转换为另一个类型并返回,可能具有不同的cvqualification,应产生原始指针值。
这似乎没有被纳入C中。
当然,你不能相互转换它们的原因是它们可能没有相同的大小或格式。Posix要求它们具有相同的大小和格式,并且我希望所有Posix编译器都支持转换;以前大多数人都这样做了,尽管这使它们不符合规范。
编辑:
更多信息。重新阅读C标准后,我认为对象指针和函数指针之间的转换是未定义的行为:C标准似乎不需要在这种情况下发出诊断,但它肯定不会为其定义任何行为。作为未定义的行为,一个实现(或Posix)可以自由定义它。或者就像不记录它一样随便做什么。
另一方面,C++在C++11之前需要发出诊断(尽管许多编译器没有发出诊断)。根据上面引用的段落,在C++11中,是否支持转换是实现定义的,如果一个实现支持它,它们必须记录其行为。因此,在所有情况下,实现都需要记录它所做的,并且如果代码尝试执行转换,则需要发出诊断。
*(void**)ptr = dlsym(...);
的东西。 - James Kanze
void*
的定义是可以容纳任何数据指针。函数指针(以及对于 C++ 中的成员指针)则完全不同。尽管 POSIX 允许将函数指针赋值给void*
(在 C 标准的J.5.7 函数指针转换
中甚至被列为常见扩展)。 - Deduplicator