问题
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