函数指针的 void* 是什么?

What's the void* of function pointers?

我正在尝试编译一些旧代码。

根据编译器的不同,当我尝试将函数指针分配给 void* 指针时,我得到这个 warning/error:

warning: a value of type "double (*)(double, double)" cannot be assigned to an entity of type "void *"
error: invalid conversion from ‘double (*)(double, double)’ to ‘void*’

我认为旧代码用于在旧编译器上编译,但我知道该代码是非法的,不应编译。我想知道函数是否也有 void*。到目前为止我已经试过了:

double sum(double a, double b){return a+b;}

typedef double(*dDd)(double, double);
typedef void(*vFun)(void);
dDd   funPtr  = sum;  // compiles and works
void* vFunPtr = sum;  // does not compile   
vFun  vFun_p  = sum;  // does not compile   

但是编译失败。

我该如何解决这个问题?如果 void* 也适用于函数,我会很高兴。

在 C 中,

void* 可以毫无问题地 to/from 转换为 对象 指针。

sumvoid* vFunPtr = sum; 一样,不会转换为对象指针,而是函数指针。

函数指针和void *的大小可能不同。将函数指针转换为 void* 可能会丢失信息。类似于 some_int = some_long;。信息可能会丢失。

vFun vFun_p = sum; 需要类型转换但在其他方面有效:vFun vFun_p = (vFun) sum;.

void* 不是 通用指针 指针类型。

What's the void* of function pointers?

在某种程度上:所有指向函数的指针。

指向void的指针的一个特殊之处在于它可以指向任何对象,并且任何对象指针都可以转换为指向void的指针并返回,从而产生原始指针。

所有指向函数的指针都可以转换为其他指向函数类型的指针,然后再转换回来,产生原始值。


换句话说:函数指针没有类似的指针类型,因为没有这样的指针类型,所有函数指针类型都可以隐式转换为,就像对象指针隐式转换为 void*.


How can I fix this?

如果需要,使用强制转换显式转换指针。在 C++ 中使用 reinterpret_cast

P.S。转换为 void* 不能保证在所有系统上都有效,因此不能普遍移植。根据 C++ 标准,它是 "conditionally supported"。它保证在 POSIX 符合标准的系统中工作。

函数指针没有指定泛型。但是,您可以为它使用任何函数指针类型。 C 标准说任何函数指针都可以转换为任何函数指针类型。 (当然,使用转换后的指针调用函数只有在调用的类型与函数的实际定义兼容的情况下才被定义。)