Which data type to be used for a "generic" function pointer?
According to the answers to various questions on this web site (link, link, link), it is not allowed to cast a function pointer to a data pointer.
This makes sense to me because there are some CPU architectures where a function pointer is longer than a data pointer: By casting a function pointer to a data pointer, data will get lost.
A historic example for desktop programs would be x86-16 with "medium" memory layout (sizeof(void (*)())=4
, sizeof(void *)=2
); you still find this behavior in some modern (mainly non-desktop) CPUs.
If a variable shall hold a pointer to "unknown" data, you use the data type void *
.
I'm currently writing a program where a variable may hold a pointer to an "unknown" function (just like the value returned by dlsym()
in Linux or GetProcAddress()
in Windows):
// ---- file1.c ----
typedef /* What to use here? */ functionPointer;
...
functionPointer myPointer, myPointer2;
myPointer = getFunction(1);
myPointer2 = getFunction(2);
...
double (*fptr)(double, void *) = myPointer2;
...
// ---- file2.c ----
void func1(void);
double func2(double x, void * y);
functionPointer getFunction(int which)
{
switch(which)
{
case 1: return &func1;
case 2: return &func2;
...
}
}
Which data type would be used in such a situation if the program should be platform independent?
If there is no solution that works on all platforms (desktop, microcontrollers, DSP, GPU etc.):
Is there a solution that works on all desktops?
Solution 1:
For a generic function pointer, use any function pointer type.
C 2018 6.3.2.3 8 says:
A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer…
This means that you can convert any function pointer to a different type of function pointer. As long as you convert it back to the original type when calling the function, the behavior is defined, and it will correctly call the original function.
C does not provide a designated generic function pointer type, like void *
for objects. You just pick one for your program, like void (*)()
, and use that.