предупреждение о указателе функции C - PullRequest
1 голос
/ 09 ноября 2010

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

#include <stdlib.h>
#include <stdio.h>

typedef void (*func_t)(void * data);

void func2(int * arg, func_t free_func) {
        free_func(arg);
}

void func(int * a) {
        printf("%d\n", *a);
}

int main(int argc, char ** argv) {
        int a = 4;
        func2(&a, func);
        return 0;
}

Компиляция, которая выдает мне предупреждение: передача аргумента 2 `func2 'из несовместимого типа указателя

Почему это так?Разве int-указатель не должен быть совместимым с void-указателем?

Ответы [ 4 ]

3 голосов
/ 09 ноября 2010

То, что вы можете приводить типы, не означает, что компилятор с радостью сделает это за вас.

В этом случае определение указателя функции не совпадает. C не будет предполагать, что функция, объявленная для получения int*, будет рада вместо void*, даже если преобразование между этими двумя типами неявно. Это тонкое замечание в том, как C обрабатывает указатели на функции.

Если вы хотите, чтобы это работало без предупреждений, вам придется разыграть следующее:

func2(%a, (func_t)func);
1 голос
/ 10 ноября 2010

Типы указателей совместимы, только если их базовые типы совместимы, а int и void не совместимы.

Кроме того, указатели типа int и void могут иметь разные размеры и представления.

1 голос
/ 10 ноября 2010

Вы также можете сделать это:

free_func((int *)arg);

Обратите внимание, что преобразование пустоты * в T * (в данном случае int *) небезопасно из-за побочных эффектовиспользуя T *, который на самом деле не указывает на T

, например

char i = 0;
char j = 0;    
char* p = &i;
void* q = p;
int* pp = q;    /* unsafe, legal C, not C++ */
printf("%d %d\n",i,j);
*pp = -1;   /* overwrite memory starting at &i */
 printf("%d %d\n",i,j);
0 голосов
/ 10 ноября 2010

Если вы измените объявление / определение функции на

void func(void * a) {
        printf("%d\n", *(int*)a);
}

все работает так, как вы ожидаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...