Предупреждение при переводе типов между указателем и указателем к функции

StackOverflow https://stackoverflow.com/questions/1556651

  •  21-09-2019
  •  | 
  •  

Вопрос

Я переношу код C в среду чипа Ti DSP. Я борюсь с компилятором C.

У меня есть структура данных, которая включает указатель на функцию. У меня есть функция, которая инициализирует структуру данных. Что-то вроде этого:

typedef void (*PFN_FOO)(int x, int y);

struct my_struct
{
    PFN_FOO pfn;
};

init_struct(struct my_struct *p, void *pfn)
{
    p->pfn = (PFN_FOO)pfn;
}

Под Visual Studio и GCC такого рода компилирования кода без жалоб. На самом деле, потому что pfn Аргумент тип void * Мне действительно не нужно даже ставить там актерский состав; Это просто неявно бросает без жалоб.

В Code Composer Studio для чипов Ti DSP я получаю «Предупреждение: неверное преобразование типа»

Моя политика состоит в том, чтобы сделать мой код компиляцией без предупреждений, поэтому я хочу это исправить. Я пробовал всевозможные кастинги. Я обнаружил, что компилятор совершенно счастлив, если я сбрось void * указатель на int сначала, а затем бросьте его на правильный тип. Эв, ты!

Как я могу сделать этот актерский состав без жалоб компилятора? Мне действительно нужно бросить на int Чтобы заткнуть компилятор?

Примечание: я специально нет Ищу решение влияния «Изменения init_struct() Принять а PFN_FOO вместо void *«Это будет работать для этого упрощенного фрагмента кода, но не будет работать для фактического кода, который составляет список, возможно, неоднородные вещи.

Это было полезно?

Решение

Стандартный C, в частности, не поддерживает конверсии между указателями в объекты данных и указателями на функции. GCC и Visual Studio поддерживают это как расширение.

Если вы хотите сделать свою функцию стандартной конформированием (но все же используйте void * Параметр), вы можете передать указатель на указатель функции. Это работает, потому что сами указатели функций являются обычными объектами, поэтому указатель на указатель функции может быть преобразован в и обратно void * просто хорошо:

init_struct(struct my_struct *p, void *pfn)
{
    PFN_FOO *foo = pfn;
    p->pfn = *foo;
}

Абонент должен затем создать временный PFN_FOO объект, чтобы передать указатель, когда он делает вызов:

PFN_FOO fp = &somefunc;
/* ... */
init_struct(p, &fp);

Другие советы

Вы не должны писать?

typedef void (*PFN_FOO)(int x, int y);

Посмотри это руководство.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top