Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explicitly declaring a function pointer and not a data pointer

I am converting a program from C++ to C, using Microsoft Visual Studio. It's a Windows app, but I don't think that's relevant to this question.

I am using the /W4 switch to turn on more warning messages. I would like my program to compile with no warnings. The program compiles and runs fine. This is just about warning messages.

Before when the program was C++, it compiled with no warnings, but now that I've converted it to C as best I can, there's a warning that I do not know how to deal with.

Here is the relevant code. The idea is that I'm creating a menu system for a GUI. Each menu contains a collection of menu items, and each menu item contains a function pointer that represents the action that will be performed when the user chooses that menu item.

typedef struct MENUITEM
{
    wchar_t* Name;
    void*    Action;
} MENUITEM;

typedef struct MENU
{
    wchar_t*   Name;
    uint8_t    SelectedItem;
    uint8_t    ItemCount;
    MENUITEM** Items;
} MENU;

Elsewhere in the program, this the code that handles the event when the user chooses a menu item:

void(*FP) (void) = NULL;
FP = (void(*)())MyMenu.Items[MyMenu.SelectedItem]->Action;
FP();

Here are the compiler warnings that are generated:

C4152 nonstandard extension, function/data pointer conversion in expression

And

C4113 'void (__cdecl *)()' differs in parameter lists from 'void (__cdecl *)(void)'

The MSDN documentation for the warning message C4152 states:

A function pointer is converted to or from a data pointer. This conversion is allowed under Microsoft extensions (/Ze) but not under ANSI C.

OK, so I think this explains why it did not produce a warning as C++, but when compiling as C, it does. But I don't know how to deal with it. To be honest, I did not realize before now that there was a difference between a function pointer and a data pointer.

I cannot figure out how to change the declaration of my function pointer such that it is explicit to the compiler that this is a function pointer, not a data pointer.

like image 332
Ryan Ries Avatar asked Jan 10 '16 02:01

Ryan Ries


1 Answers

You probably need this (with a 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;
}
like image 148
Danny_ds Avatar answered Oct 19 '22 21:10

Danny_ds