将指针存储在void*中的函数指针

jay*_*jay 7 c pointers function-pointers

我明白你为什么不能这样做:

void(*fp)(void) = &function;
function_taking_void_pointer((void*)fp);
Run Code Online (Sandbox Code Playgroud)

因为类型的长度可能不同.

但是添加另一个间接层是否有任何问题:

void(*fp)(void) = &function;
void(**fpp)(void) = &fp;
function_taking_void_pointer((void*)fpp)
Run Code Online (Sandbox Code Playgroud)

我在这背后的想法:指向函数指针的指针应指向数据存储器,因此应该与void*类型具有相同的长度.

那我有多难?

use*_*733 4

你是对的,所有指针类型都是对象类型

\n\n

N1570 6.3.5 类型,第 20 段,第五列表项:

\n\n
\n
    \n
  • 指针类型可以派生自函数类型或对象类型,称为引用类型。指针类型描述一个对象,其值提供对所引用类型的实体的引用。从引用类型 T\n 派生的指针类型有时称为 \xe2\x80\x98\xe2\x80\x98,指向 T\xe2\x80\x99\xe2\x80\x99 的指针。从引用类型构造指针类型称为\xe2\x80\x98\xe2\x80\x98指针类型派生\xe2\x80\x99\xe2\x80\x99。指针类型是完整的对象类型。
  • \n
\n
\n\n

但指向对象类型的指针不一定具有与void*(6.2.5 p28) 相同的大小。

\n\n
\n
    \n
  1. 指向 void 的指针应与指向字符类型的指针具有相同的表示和对齐要求。48)同样,指向兼容类型的限定或非限定版本的指针应具有相同的表示和对齐要求。所有指向结构类型的指针应具有相同的表示和对齐要求。所有指向联合类型的指针应具有相同的表示形式和彼此的对齐要求。指向其他类型的指针不需要具有相同的表示或对齐要求。
  2. \n
\n
\n\n

然而,它们都可以转换void*(6.3.2.3 p1):

\n\n
\n
    \n
  1. 指向 void 的指针可以与指向任何对象类型的指针相互转换。指向任何对象类型的指针都可以转换为指向 void 的指针,然后再转换回来;比较结果应等于原始指针。
  2. \n
\n
\n

  • 该标准没有提及将函数指针类型转换为“void *”;您明确引用了它的内容:_A **指向 void** 的指针可以转换为 **指向任何对象类型**的指针**。_ 函数不是对象;它是对象。这就是为什么它说_指针类型可以派生自函数类型**或**对象类型_;两组类型(指向对象的指针和指向函数的指针)不同,并且不一定可以转换。POSIX 甚至删除了用于提供 get-out 子句的文本。有些机器的函数指针非常复杂(大、复杂)。 (2认同)