C 将指向函数指针的指针存储在空中*

C 将指向函数指针的指针存储在空中*,c,pointers,function-pointers,C,Pointers,Function Pointers,我理解你为什么不能: void(*fp)(void) = &function; function_taking_void_pointer((void*)fp); 因为类型的长度可能不同 但是添加其他间接层有什么问题吗: void(*fp)(void) = &function; void(**fpp)(void) = &fp; function_taking_void_pointer((void*)fpp) 我的想法是:指向函数指针的指针应该指向数据内存,因此应该与vo

我理解你为什么不能:

void(*fp)(void) = &function;
function_taking_void_pointer((void*)fp);
因为类型的长度可能不同

但是添加其他间接层有什么问题吗:

void(*fp)(void) = &function;
void(**fpp)(void) = &fp;
function_taking_void_pointer((void*)fpp)
我的想法是:指向函数指针的指针应该指向数据内存,因此应该与void*类型具有相同的长度


那么我错了多少?

这个代码片段错了

void(*fp)(void) = &function; function_taking_void_pointer((void*)fp); void(*fp)(void)=&函数; 函数取void指针((void*)fp);
在C/C++中,
函数名
将被重新定位到
链接阶段
中的特定地址,因此您不能在
函数名
之前使用
&
。此外,
函数名
在C/C++中不是变量,因此您也无法尝试获取其地址。

所有指针类型都是对象类型,这是正确的:

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

  • 指针类型可以从函数类型或对象类型派生,称为 引用类型。指针类型描述其值提供引用的对象 指向引用类型的实体。从引用类型T派生的指针类型 有时称为“指向T的指针”。从 引用的类型称为“指针类型派生”指针类型是完整的 对象类型。
但是指向对象类型的指针的大小不一定与
void*
(6.2.5 p28)相同

  • 指向void的指针应与 指向字符类型的指针。48)类似地,指针指向 兼容类型应具有相同的表示和对齐要求。全部的 指向结构类型的指针应具有相同的表示和对齐要求 就像我们彼此一样。所有指向联合类型的指针应具有相同的表示形式和 校准要求彼此一致指向其他类型的指针不必具有相同的 表示或对齐要求。
  • 但是,它们都可以转换为
    void*
    (6.3.2.3 p1):

  • 指向void的指针可以转换为指向任何对象类型的指针,也可以转换为指向任何对象类型的指针。指向 任何对象类型都可以转换为指向void并返回的指针;结果将是 比较等于原始指针

  • 上帝保佑,当你完成这段代码的时候,任何需要阅读它的人……当然,空指针是为这类“黑客”设计的。但是我想传递一个函数指针到一个函数,这个函数可能是为了处理不同的数据类型,比如int*、float*、double*、struct which*等等,这绝对不是一个好的设计。所以我认为你最好写一个函数,参数是指向函数的指针。好的,请记住,函数指针可以存储在任何其他函数指针中(通过强制转换),只要它在用于进行函数调用之前被强制转换回正确的函数指针类型。因此,您可以使用
    void(*)(void)
    (或任何函数指针类型)作为函数指针的“void*”类型。此外,POSIX排序要求函数指针可以通过
    void*
    往返,因为
    dlsym()
    函数是如何指定的。如果
    foo()
    是函数,您可以使用
    &foo
    。这与使用
    foo
    本身是一样的。与静态分配数组相同。您可以包括
    &
    ,也可以省略
    &
    。编译器将以同样的方式对其进行解释。该标准没有说明如何将函数指针类型转换为
    void*
    ;您明确引用了它所说的话:指向void的指针可以转换为指向任何对象类型的指针,也可以转换为指向任何对象类型的指针。功能不是对象;这就是为什么它说指针类型可以从函数类型或对象类型派生;这两组类型(指向对象的指针和指向函数的指针)并不相同,也不一定是可转换的。POSIX甚至删除了用于提供get out子句的文本。有些机器的函数指针非常精细(大,复杂)。@JonathanLeffler是的,这就是我的答案。请记住,关于函数指针指针的问题。这是对象类型,可以转换为
    void*