can void*用于存储函数指针?

Ven*_*esh 14 c c++ function-pointers void-pointers

void*以这样的方式定义,它可以指向任何东西.那么它可以用来指向一个函数(int send())吗?

int send();
void* p = send;
Run Code Online (Sandbox Code Playgroud)

可能吗?当我这样使用时,它没有向我显示错误原因?如果没有,有没有办法将所有指针存储在一个变量中?

Vla*_*cow 16

不,它可能没有.

根据C标准(6.3.2.3指针)

1指向void的指针可以转换为指向任何对象类型的指针 .指向任何对象类型的指针可以转换为指向void的指针,然后再返回; 结果应该等于原始指针.

至于函数指针那么

8指向一种类型的函数的指针可以转换为指向另一种类型的函数的指针,然后再返回; 结果应该等于原始指针.如果转换的指针用于调用类型与引用类型不兼容的函数,则行为未定义.

在C++标准中有更详细的指针定义(3.9.2复合类型)

3 指向void的指针类型或指向对象类型的指针称为对象指针类型 ....可以指定函数的指针类型称为函数指针类型.

4 指向cv合格(3.9.3)或CV-不合格空隙可被用于指向邻bjects未知类型的.这样的指针应该能够保存任何对象指针.cv void*类型的对象应具有与cv char*相同的表示和对齐要求.

  • 但是POSIX确实要求定义转换,并且要求它们具有相同的大小和表示,作为`dlsym`需求的一部分. (2认同)

Jam*_*nze 16

也许.直到C++ 11,他们不能; 但C++ 11补充说:

有条件地支持将函数指针转换为对象指针类型(反之亦然).这种转换的含义是实现定义的,除非实现支持两个方向的转换,将一种类型的prvalue转换为另一种类型并返回,可能具有不同的cvqualification,将产生原始指针值.

这似乎还没有成为C.

当然,你无法在它们之间进行转换的原因是它们可能没有相同的大小或格式.Posix要求它们具有相同的大小和格式,我希望所有Posix编译器都支持转换; 无论如何,大多数人都做过,尽管它使它们不符合要求.

编辑:

更多信息.在重新阅读C标准之后,我认为对象指针和函数指针之间的转换是未定义的行为:在这种情况下,C标准似乎不需要诊断,但它肯定没有为它定义任何行为.作为未定义的行为,实现(或Posix)可以自由定义它.或者只是做任何想做的事情而不记录它.

另一方面,C++,pre C++ 11,需要一个诊断(虽然许多编译器没有给出一个).在C++ 11中,根据上面引用的段落,实现定义了实现是否支持它,如果实现支持它,则需要记录它的行为.因此,在所有情况下,都需要一个实现来记录它的作用,如果它不支持它,则需要在代码尝试进行转换时发出诊断.