简体   繁体   English

哪种数据类型用于“通用”function 指针?

[英]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.根据此 web 站点( 链接链接链接)上各种问题的答案,不允许将 function 指针转换为数据指针。

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.这对我来说很有意义,因为在某些 CPU 架构中,function 指针比数据指针长:通过将 function 指针转换为数据指针,数据将丢失。

A historic example for desktop programs would be x86-16 with "medium" memory layout ( sizeof(void (*)())=4 , sizeof(void *)=2 );桌面程序的一个历史示例是 x86-16 与“中等”memory 布局( sizeof(void (*)())=4 , sizeof(void *)=2 ); you still find this behavior in some modern (mainly non-desktop) CPUs.您仍然会在一些现代(主要是非桌面)CPU 中发现这种行为。

If a variable shall hold a pointer to "unknown" data, you use the data type void * .如果变量应包含指向“未知”数据的指针,则使用数据类型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):我目前正在编写一个程序,其中一个变量可能包含一个指向“未知”function 的指针(就像 Linux 中的dlsym()或 Windows 中的GetProcAddress()返回的值一样):

// ---- 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.):如果没有适用于所有平台(台式机、微控制器、DSP、GPU 等)的解决方案:

Is there a solution that works on all desktops?是否有适用于所有桌面的解决方案?

For a generic function pointer, use any function pointer type.对于通用 function 指针,请使用任何 function 指针类型。

C 2018 6.3.2.3 8 says: 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;指向一种类型的 function 的指针可以转换为指向另一种类型的 function 的指针,然后再返回; 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.这意味着您可以将任何 function 指针转换为不同类型的 function 指针。 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.只要在调用function时将其转换回原来的类型,就定义了行为,它会正确调用原来的function。

C does not provide a designated generic function pointer type, like void * for objects. C 不提供指定的通用 function 指针类型,如对象的void * You just pick one for your program, like void (*)() , and use that.您只需为您的程序选择一个,例如void (*)() ,然后使用它。

You included "GPU" in the list of platforms.您在平台列表中包含“GPU”。 Some GPUs do not even support true function calls but just inlining & unrolling (ie in OpenCL).一些 GPU 甚至不支持真正的 function 调用,而只是内联和展开(即在 OpenCL 中)。 Same with "goto" command.与“goto”命令相同。 It's not allowed to even enter from another entrance point of a function.从 function 的另一个入口点甚至不允许进入。

If you can, sort the array of function identifiers (that hints about which function is to be called).如果可以的话,对 function 标识符的数组进行排序(提示要调用哪个 function)。 Then separate different chunks into different arrays, then call them in their own kernels.然后将不同的chunk分成不同的arrays,然后在各自的内核中调用。 If there are 100 different functions, then you could call all of them in their own kernels after the array is sorted.如果有 100 个不同的函数,那么您可以在数组排序后在它们自己的内核中调用它们。 This even optimizes for the branching performance problem of the GPU shaders.这甚至优化了 GPU 着色器的分支性能问题。 After kernels complete, you can continue main algorithm.内核完成后,您可以继续主算法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM