Я конвертирую программу из C++ в C с помощью Microsoft Visual Studio. Это приложение для Windows, но я не думаю, что это относится к этому вопросу.Явное объявление указателя функции, а не указателя данных
Я использую переключатель /W4
для включения дополнительных предупреждающих сообщений. Я хотел бы, чтобы моя программа компилировалась без предупреждений. Программа компилируется и работает нормально. Это всего лишь предупреждение.
Прежде, чем программа была C++, она скомпилирована без предупреждений, но теперь, когда я как можно лучше ее преобразовал в C, появляется предупреждение, что я не знаю, как с этим бороться.
Вот соответствующий код. Идея состоит в том, что я создаю систему меню для графического интерфейса. Каждое меню содержит набор элементов меню, и каждый пункт меню содержит указатель функции, который представляет действие, которое будет выполняться, когда пользователь выбирает этот пункт меню.
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 'недействительным (__cdecl *)()' отличается в списках параметров из 'пустоты (__cdecl *) (ничтожной)'
MSDN documentation для предупреждающего сообщения C4152 гласит:
Указатель функции преобразуется в указатель данных или из него. Это преобразование разрешено в расширениях Microsoft (/ Ze), но не под ANSI C.
ОК, поэтому я думаю, что это объясняет, почему оно не выдавало предупреждение как C++, но при компиляции как C оно делает. Но я не знаю, как с этим бороться. Честно говоря, я до сих пор не осознавал, что существует разница между указателем на функцию и указателем данных.
Я не могу понять, как изменить объявление моего указателя на функцию, чтобы он был явным компилятору, что это указатель на функцию, а не указатель данных.
Danny_ds был хорош, но ИМО этот ответ был лучшим. Теперь код не только компилируется без предупреждений, но также позволяет мне исключить дополнительное локальное объявление FP в моем коде и использовать только «MyMenu».Элементы [MyMenu.SelectedItem] -> Action(); ' –
@RyanRies. Просто, чтобы быть ясным: что, конечно, необязательная локальная декларация не требуется - она была там для ясности, чтобы показать использование. Использование typedef для указателей функций обычно является хорошей идеей. –
@ Danny_ds I See. Спасибо. Оба ваших ответа ценны. Я думаю, что оба ваших ответа, когда они были сделаны в сочетании, помогли ему «щелкнуть» для меня. Хотел бы я принять их обоих. –