显式声明函数指针而不是数据指针
Explicitly declaring a function pointer and not a data pointer
我正在使用 Microsoft Visual Studio 将程序从 C++ 转换为 C。这是一个 Windows 应用程序,但我认为这与这个问题无关。
我正在使用 /W4
开关打开更多警告消息。我希望我的程序在没有警告的情况下编译。该程序编译并运行良好。这只是警告消息。
之前程序是C++,编译时没有任何警告,但现在我已经尽力将它转换为C,出现了一个我不知道如何处理的警告。
这是相关代码。我的想法是我正在为 GUI 创建一个菜单系统。每个菜单包含一个菜单项集合,每个菜单项包含一个函数指针,表示当用户选择该菜单项时将执行的操作。
typedef struct MENUITEM
{
wchar_t* Name;
void* Action;
} MENUITEM;
typedef struct MENU
{
wchar_t* Name;
uint8_t SelectedItem;
uint8_t ItemCount;
MENUITEM** Items;
} MENU;
在程序的其他地方,这是在用户选择菜单项时处理事件的代码:
void(*FP) (void) = NULL;
FP = (void(*)())MyMenu.Items[MyMenu.SelectedItem]->Action;
FP();
以下是生成的编译器警告:
C4152 nonstandard extension, function/data pointer conversion in expression
和
C4113 'void (__cdecl *)()' differs in parameter lists from 'void (__cdecl *)(void)'
警告消息 C4152 的 MSDN documentation 指出:
A function pointer is converted to or from a data pointer. This conversion is allowed under Microsoft extensions (/Ze) but not under ANSI C.
好的,所以我认为这解释了为什么它没有像 C++ 那样产生警告,但在像 C 一样编译时会产生警告。但我不知道如何处理它。老实说,我以前没有意识到函数指针和数据指针之间有区别。
我不知道如何更改函数指针的声明,以便编译器明确知道这是函数指针,而不是数据指针。
您可能需要这个(带有 typedef
):
typedef void(*FP) (void);
typedef struct MENUITEM
{
wchar_t* Name;
FP Action;
} MENUITEM;
int main() {
MENUITEM it;
// ... more code
FP fp = it.Action;
fp();
return 0;
}
您忘记了演员表中的 void
。这就是 C4113 告诉你的。
您可以通过将 Action
声明为函数指针来完全避免强制转换:
void (*Action)(void);
我正在使用 Microsoft Visual Studio 将程序从 C++ 转换为 C。这是一个 Windows 应用程序,但我认为这与这个问题无关。
我正在使用 /W4
开关打开更多警告消息。我希望我的程序在没有警告的情况下编译。该程序编译并运行良好。这只是警告消息。
之前程序是C++,编译时没有任何警告,但现在我已经尽力将它转换为C,出现了一个我不知道如何处理的警告。
这是相关代码。我的想法是我正在为 GUI 创建一个菜单系统。每个菜单包含一个菜单项集合,每个菜单项包含一个函数指针,表示当用户选择该菜单项时将执行的操作。
typedef struct MENUITEM
{
wchar_t* Name;
void* Action;
} MENUITEM;
typedef struct MENU
{
wchar_t* Name;
uint8_t SelectedItem;
uint8_t ItemCount;
MENUITEM** Items;
} MENU;
在程序的其他地方,这是在用户选择菜单项时处理事件的代码:
void(*FP) (void) = NULL;
FP = (void(*)())MyMenu.Items[MyMenu.SelectedItem]->Action;
FP();
以下是生成的编译器警告:
C4152 nonstandard extension, function/data pointer conversion in expression
和
C4113 'void (__cdecl *)()' differs in parameter lists from 'void (__cdecl *)(void)'
警告消息 C4152 的 MSDN documentation 指出:
A function pointer is converted to or from a data pointer. This conversion is allowed under Microsoft extensions (/Ze) but not under ANSI C.
好的,所以我认为这解释了为什么它没有像 C++ 那样产生警告,但在像 C 一样编译时会产生警告。但我不知道如何处理它。老实说,我以前没有意识到函数指针和数据指针之间有区别。
我不知道如何更改函数指针的声明,以便编译器明确知道这是函数指针,而不是数据指针。
您可能需要这个(带有 typedef
):
typedef void(*FP) (void);
typedef struct MENUITEM
{
wchar_t* Name;
FP Action;
} MENUITEM;
int main() {
MENUITEM it;
// ... more code
FP fp = it.Action;
fp();
return 0;
}
您忘记了演员表中的 void
。这就是 C4113 告诉你的。
您可以通过将 Action
声明为函数指针来完全避免强制转换:
void (*Action)(void);