"generic" 函数指针使用哪种数据类型?
Which data type to be used for a "generic" function pointer?
根据本站各种问题的回答(link, link, link),不允许将函数指针转换为数据指针。
这对我来说很有意义,因为在某些 CPU 架构中,函数指针比数据指针长:通过将函数指针转换为数据指针,数据将会丢失。
桌面程序的历史示例是具有“中等”内存布局的 x86-16(sizeof(void (*)())=4
、sizeof(void *)=2
);您仍然会在某些现代(主要是非桌面)CPUs.
中发现这种行为
如果变量应包含指向“未知”数据的指针,则使用数据类型 void *
。
我目前正在编写一个程序,其中变量可能包含指向“未知”函数的指针(就像 Linux 中的 dlsym()
或 Linux 中的 GetProcAddress()
返回的值一样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;
...
}
}
如果程序应该与平台无关,在这种情况下会使用哪种数据类型?
如果没有适用于所有平台(桌面、微控制器、DSP、GPU 等)的解决方案:
是否有适用于所有桌面的解决方案?
您在平台列表中加入了“GPU”。有些 GPU 甚至不支持真正的函数调用,而只支持内联和展开(即在 OpenCL 中)。与“goto”命令相同。甚至不允许从函数的另一个入口点进入。
如果可以,对函数标识符数组进行排序(提示要调用哪个函数)。然后把不同的chunk分成不同的数组,然后在各自的kernel中调用。如果有 100 个不同的函数,那么你可以在数组排序后在它们自己的内核中调用所有这些函数。这甚至优化了 GPU 着色器的分支性能问题。内核完成后,您可以继续主要算法。
对于通用函数指针,使用任何函数指针类型。
C 2018 6.3.2.3 8 说:
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…
这意味着您可以将任何函数指针转换为不同类型的函数指针。只要你在调用函数的时候把它转回原来的类型,定义了行为,就会正确调用原来的函数。
C 不提供指定的通用函数指针类型,如 void *
对象。您只需为您的程序选择一个,例如 void (*)()
,然后使用它。
根据本站各种问题的回答(link, link, link),不允许将函数指针转换为数据指针。
这对我来说很有意义,因为在某些 CPU 架构中,函数指针比数据指针长:通过将函数指针转换为数据指针,数据将会丢失。
桌面程序的历史示例是具有“中等”内存布局的 x86-16(sizeof(void (*)())=4
、sizeof(void *)=2
);您仍然会在某些现代(主要是非桌面)CPUs.
如果变量应包含指向“未知”数据的指针,则使用数据类型 void *
。
我目前正在编写一个程序,其中变量可能包含指向“未知”函数的指针(就像 Linux 中的 dlsym()
或 Linux 中的 GetProcAddress()
返回的值一样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;
...
}
}
如果程序应该与平台无关,在这种情况下会使用哪种数据类型?
如果没有适用于所有平台(桌面、微控制器、DSP、GPU 等)的解决方案:
是否有适用于所有桌面的解决方案?
您在平台列表中加入了“GPU”。有些 GPU 甚至不支持真正的函数调用,而只支持内联和展开(即在 OpenCL 中)。与“goto”命令相同。甚至不允许从函数的另一个入口点进入。
如果可以,对函数标识符数组进行排序(提示要调用哪个函数)。然后把不同的chunk分成不同的数组,然后在各自的kernel中调用。如果有 100 个不同的函数,那么你可以在数组排序后在它们自己的内核中调用所有这些函数。这甚至优化了 GPU 着色器的分支性能问题。内核完成后,您可以继续主要算法。
对于通用函数指针,使用任何函数指针类型。
C 2018 6.3.2.3 8 说:
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…
这意味着您可以将任何函数指针转换为不同类型的函数指针。只要你在调用函数的时候把它转回原来的类型,定义了行为,就会正确调用原来的函数。
C 不提供指定的通用函数指针类型,如 void *
对象。您只需为您的程序选择一个,例如 void (*)()
,然后使用它。