C: How to access a function pointer stored in a void pointer (void *)?

大憨熊 提交于 2019-12-11 17:53:06

问题


Confused as to how one can access a function pointer stored in a void pointer (void *).


Let's say you have this:

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

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

If I wanted to access the sqrt function, my guess would be the following:

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

But my guess is wrong:

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


So how would one access one of these functions ?


回答1:


It's a matter of operator precedence: The function call operator have higher precedence than the casting operator.

That means your expression (int (*)(int)) functions[0](x) is really equal to (int (*)(int)) (functions[0](x)).

You need to explicitly add parentheses in the correct places to cast the pointer: ((int (*)(int)) functions[0])(x).


A much better solution IMO would be to have an array of pointers to functions, so the array elements already is of the correct type:

typedef int (*function_ptr)(int);

function_ptr functions[] = { ... };

Then no casting is needed: functions[0](x).

Then you also would be safe from the issues mentioned in the answer by Lundin.




回答2:


Strictly speaking, you can't. A conversion between a function pointer and a void pointer is not possible. void* was never a generic pointer type for function pointers, only for object pointers. They are not compatible types.

In practice, any pointer will very likely have the size required by the address bus of the system, so object pointers and function pointers will very likely have the same representation. Not guaranteed by the standard though, and there are some exotic systems where this equivalence doesn't hold true. So you can cast between void* and a function pointer, but what will happen is undefined behavior. You will be relying on system-specific non-standard extensions.

Slightly better would be to use a function pointer type such as void (*)(void) as the generic pointer. You can convert to/from different function pointers, what will happen is compiler-specific (implementation-defined behavior). That is, the code will still be non-portable, but at least you don't risk a program crash from invoking undefined behavior.



来源:https://stackoverflow.com/questions/52070882/c-how-to-access-a-function-pointer-stored-in-a-void-pointer-void

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!