根據本網站上各種問題的答案(鏈接、鏈接、鏈接),不允許將函式指標強制轉換為資料指標。
這對我來說很有意義,因為在某些 CPU 體系結構中,函式指標比資料指標長:通過將函式指標轉換為資料指標,資料會丟失。
桌面程式的一個歷史示例是具有“中等”記憶體布局 ( sizeof(void (*)())=4, sizeof(void *)=2) 的 x86-16;您仍然會在一些現代(主要是非桌面)CPU 中發現這種行為。
如果變數應包含指向“未知”資料的指標,則使用資料型別void *。
我目前正在撰寫一個程式,其中一個變數可能包含一個指向“未知”函式的指標(就像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 等)的解決方案:
是否有適用于所有桌面的解決方案?
uj5u.com熱心網友回復:
對于通用函式指標,請使用任何函式指標型別。
C 2018 6.3.2.3 8 說:
指向一種型別的函式的指標可以轉換為指向另一種型別的函式的指標,然后再回傳;結果應與原始指標相等...
這意味著您可以將任何函式指標轉換為不同型別的函式指標。只要你在呼叫函式的時候把它轉換回原來的型別,行為就定義好了,它就會正確呼叫原來的函式。
C 不提供指定的通用函式指標型別,如void *物件。您只需為您的程式選擇一個,例如void (*)(),然后使用它。
uj5u.com熱心網友回復:
您在平臺串列中包含“GPU”。有些 GPU 甚至不支持真正的函式呼叫,而只是行內和展開(即在 OpenCL 中)。與“goto”命令相同。甚至不允許從函式的另一個入口點進入。
如果可以的話,對函式識別符號陣列進行排序(暗示要呼叫哪個函式)。然后將不同的塊分成不同的陣列,然后在各自的內核中呼叫它們。如果有 100 個不同的函式,那么您可以在陣列排序后在它們自己的內核中呼叫它們。這甚至優化了 GPU 著色器的分支性能問題。內核完成后,您可以繼續主演算法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/419668.html
標籤:
上一篇:為什么sizeof()在這個例子中不包含NUL位元組?
下一篇:在函式中初始化指標
