将 void (*p)(SomeType*) 转换为 void (*p)(void*) 是否安全?

Is it safe to cast void (*p)(SomeType*) to void (*p)(void*)

本文关键字:void 安全 是否 转换 SomeType      更新时间:2023-10-16

假设我有一个如下函数:

void fun(void* p){
    SomeType* p = reinterpret_cast<SomeType*>(p);
    ...
}

API 需要签名。我只是想知道我能不能把它写成。

void fun(SomeType* p){
    ...
}

并将其投射到void (*)(void*).

虽然可以将函数指针强制转换为其他函数指针并返回,但通过与其签名不匹配的指针调用函数是未定义的行为。您不能只是强制转换它并传递给 API。

在 C 和 C++03 中,您必须创建一个与签名匹配并预执行强制转换的命名包装函数。在 C++11 及更高版本中,您可以改用无捕获的 lambda(正确转换(:

void fun(SomeType* p){
    ...
}
int main() {
  api_call(+[](void *v) {
    fun(static_cast<SomeType*>(v));
  });
}

lambda 前面的+会导致它被转换为常规函数指针,只要它没有捕获。这不是严格需要的,但它使意图更加明确 IMO,没有太多冗长。