我正在使用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非标准扩展,表达式中的函数/数据指针转换
和
C4113'void(__ cdecl *)()'参数列表与'void(__ cdecl *)(void)'
不同
警告信息C4152的MSDN documentation声明:
函数指针转换为数据指针或从数据指针转换。在Microsoft扩展(/ Ze)下允许此转换,但在ANSI C下不允许。
好的,所以我认为这解释了为什么它没有像C ++那样产生警告,但是当编译为C时,它确实如此。但我不知道如何处理它。说实话,我之前没有意识到函数指针和数据指针之间存在差异。
我无法弄清楚如何更改函数指针的声明,以便编译器明确指出这是函数指针,而不是数据指针。
答案 0 :(得分:5)
你可能需要这个(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;
}
答案 1 :(得分:3)
你忘记了演员阵容中的Action
。这就是C4113告诉你的。
您可以通过将void (*Action)(void);
声明为函数指针来完全避免强制转换:
int