обратный вызов с аргументом указателя void выдает предупреждение

У меня есть следующий код:

/* callback taking a pointer to a "generic" msg as argument */
typedef void (*Callback_t)(void *msg);

/* initialize callback pointer */
Callback_t const Callback[] =
{
  ProcessMsgAction0,  /**< 0: MSGID_ACTION_0 */
  ProcessMsgAction1,  /**< 1: MSGID_ACTION_1 */
  /* ... */
};

/* Call the callback according to msgid */
msg = GetMessage();
Callback[msg->id](msg);

/* implement callback for each message id */
void ProcessMsgAction0(action0_t *msg) { /* ... */ }
void ProcessMsgAction1(action1_t *msg) { /* ... */ }

Хотя void* считался универсальным указателем. Поэтому какой бы адрес я ни дал, он не будет выдавать предупреждение, но в приведенном выше случае action0_t* отличается от void*, поэтому он выдает следующее предупреждение: initialization from incompatible pointer type

Если я хочу подавить предупреждение, могу ли я изменить аргумент ProcessMsgAction на void* единственным решением?

Используемая опция компиляции: -ansi -pedantic -Wall -Wextra


person Phong    schedule 19.08.2014    source источник


Ответы (1)


I though void* was considered as generic pointer

Это верно, но это понятие не распространяется на сопоставление параметров в типах функций.

Однако простое приведение типов к Callback_t работает, см. этот функциональный пример на ideone.

person Alexander Gessler    schedule 19.08.2014
comment
Следует отметить, что это не определено (в зависимости от того, что OP действительно делает с указателем, но похоже, что в конечном итоге он будет неопределенным). (И также отметил, что это работает на большинстве машин, и я не могу придумать, как компилятор мог бы использовать этот UB и т. д.) И, возможно, заменить reinterpret_cast на приведение указателя в стиле C (это C вопрос, а не С++). - person mafso; 19.08.2014
comment
Я хотел бы избежать этого, но у меня нет другого выбора, кроме как использовать его. Каждое сообщение имеет разный размер структуры, но используется одинаково. - person Phong; 19.08.2014