【问题标题】:C: How to access a function pointer stored in a void pointer (void *)?C: 如何访问存储在 void 指针 (void *) 中的函数指针?
【发布时间】:2019-02-03 20:31:46
【问题描述】:

对如何访问存储在 void 指针 (void *) 中的函数指针感到困惑。


假设你有这个:

void *functions[] =
{
    &sqrt,         // int ft_sqrt(int nb);
    &power,
    &logN,
    &factorial;
};

// An array of void pointers, each storing a function pointer.

如果我想访问sqrt 函数,我的猜测如下:

(int (*)(int)) functions[0](x)

但我的猜测是错误的:

error: called object type 'void *' is not a function or function pointer


那么如何访问这些功能之一呢?

【问题讨论】:

  • 为什么要将函数指针存储在指向 void 的指针数组中? 特别是,如果您打算打电话给他们。
  • 好吧,idk,也许这不是这样做的方法,但我在想如果你有不同返回类型和/或采用不同参数的函数..你可以将它们全部存储在 1数组。
  • 如果你不知道函数的返回类型,你将如何有意义地调用它?

标签: c pointers function-pointers void-pointers typecasting-operator


【解决方案1】:

严格来说,你不能。函数指针和void 指针之间的转换是不可能的。 void* 从来不是函数指针的通用指针类型,仅适用于对象指针。它们不是兼容的类型。

实际上,任何指针很可能具有系统地址总线所需的大小,因此对象指针和函数指针很可能具有相同的表示形式。但是,标准不能保证,并且有一些奇异的系统,这种等效性并不成立。因此,您可以在 void* 和函数指针之间进行转换,但会发生未定义的行为。您将依赖系统特定的非标准扩展。

稍微好一点的方法是使用函数指针类型,例如void (*)(void) 作为通用指针。您可以在不同的函数指针之间进行转换,将会发生什么是编译器特定的(实现定义的行为)。也就是说,代码仍然是不可移植的,但至少不会因为调用未定义的行为而导致程序崩溃。

【讨论】:

  • 知道了...至于“转换到/从不同的函数指针”,这将按照您在here 中解释的方式完成。谢谢!
  • 相反安全吗?从函数指针转换为 void* 指针?
  • @thysultan "Between" 表示两种方式都无效。如果 X 与 Y 不兼容,则 Y 与 X 不兼容。
【解决方案2】:

这是operator precedence的问题:函数调用运算符的优先级高于强制转换运算符。

这意味着你的表达式(int (*)(int)) functions[0](x) 真的等于(int (*)(int)) (functions[0](x))

您需要在正确的位置显式添加括号以强制转换指针:((int (*)(int)) functions[0])(x)


IMO 更好的解决方案是有一个指针数组指向函数,因此数组元素已经是正确的类型:

typedef int (*function_ptr)(int);

function_ptr functions[] = { ... };

那么不需要强制转换:functions[0](x)

那么你也可以避免the answer by Lundin中提到的问题。

【讨论】:

  • 感谢您的回答和有用的提示一些程序员老兄,@Lundin。它现在可以工作,至少在我的系统上是这样。但肯定会考虑到可移植性问题并进行更改。
猜你喜欢
  • 1970-01-01
  • 2014-05-30
  • 2018-04-19
  • 2011-07-31
  • 1970-01-01
  • 2013-11-14
  • 2016-11-23
  • 2012-11-21
  • 1970-01-01
相关资源
最近更新 更多