2016-07-20 4 views
0

Я получаю предупреждение выше и понимаю его, но просто не знаю, как его исправить. Мой код ниже, но в основном то, что я делаю, это хранить указатель на функцию в структуре и инициализировать структуру в другой функции, которую я вызываю из моей основной. Код, кажется, компилируется, когда я использую его с функцией по умолчанию (т. Е. Free()), но не тогда, когда я использую его с помощью функции test_func ниже. Мысли?function pointer несовместимые типы указателей void (*) (void *) from void (my_type *)

Struct:

typedef struct my_struct { 
    my_type **double_pointed; 
    int num; 
    void (*funcp)(void *data); 
    } my_struct_t; 

Init Функция:

my_struct_t *init(int num, void (*my_funcp)(void *data)) { 

    // unimportant code to the problem, but basically just some mallocs for the other data 

    my_struct_t *my_str; 
    my_str->funcp = my_funcp; 

    return struct; 
} 

функция Я хочу, чтобы указать:

void desired_func(my_type *obj) {} 

мой призыв к инициализации FUNC:

init(5, desired_func); 

полная ошибка:

несовместимых типов указателей присвоение 'пустоты (*) (пустота *)' от 'пустоты (my_type *)'

на линии в функции инициализации выше:

my_struct_t *my_str; 
my_str->funcp = my_funcp; 

ответ

4

Измените типы указателей функций на соответствие функции, т.е. : (Например, различные типы параметров)

void (*funcp)(my_type *data); 

Если вы хотите, чтобы иметь возможность использовать функции с различными сигнатурами, вы можете добавить явное приведение. Например:

init(5, (void (*)(void*)) desired_func); 

Обратите внимание, что любое время desired_func функции (или любой другой функции, подпись не совпадает с указателем funcp функция) должна быть вызвана через указатель функции, указатель функции должны быть отлиты обратно в исходный тип (void (*)(my_type*) в этом случае) перед вызовом функции или вызывает неопределенное поведение.

Другой (несколько лучше) альтернатива изменить desired_func определение так:

void desired_func(void *vobj) { 
    my_type* obj = vobj; 
    /* rest of the code */ 
} 

Обратите внимание, что при вызове desired_func (через указатель на функцию или непосредственно), тип объекта, адрес которого передается как параметр должен быть my_type или разыменовать obj внутри функции (и если выравнивание отличается даже самим литьем) вызовет неопределенное поведение.

Дополнительная сложность, связанная с возможностью неопределенного поведения при кастинге (как указано выше) означает, что я бы посоветовал отказаться от кастинга - необходимость таких приводов, вероятно, свидетельствует о проблеме в вашем дизайне. То есть. вероятно, лучшее решение, если вы будете думать о своих требованиях немного больше.

+0

Проблема в том, что она должна работать со всеми типами данных, поэтому void * – bobbyyu10

+0

@ bobbyyu10: Я уже обращался к этому вопросу –

+1

Преобразование в и из 'void *' не требует приведения, поэтому 'my_type * obj = vobj; 'достаточно. – user3386109