2016-09-20 2 views
-1

을 제거하기 내 코드를 컴파일 할 때이 경고를 받고 있습니다 :호환되지 않는 포인터 경고

varfuncs.c:22:3: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] 

가 어떻게 경고없이 컴파일 할을, 또는 나는 캐스팅을 사용해야합니까?

niko: snippets $ cat varfuncs.c 
#include <stdio.h> 

typedef void (*callback_func_t)(char *param1,int param2, ...); 

void func1(char *p1,int p2); 
void func2(char *p1,int p2,float p3); 
void func3(char *p1,int p2,char *p3); 

void func1(char *p1,int p2) { 
    printf("p1=%s,p2=%d\n",p1,p2); 
} 
void func2(char *p1,int p2,float p3) { 
    printf("p1=%s,p2=%d,p3=%f\n",p1,p2,p3); 
} 
void func3(char *p1,int p2,char *p3) { 
    printf("p1=%s,p2=%d,p3=%s\n",p1,p2,p3); 
} 

int main(void) { 

    callback_func_t callback_functions[3]={ 
     func1, 
     func2, 
     func3 
    }; 

    callback_func_t cb_func; 

    cb_func=callback_functions[0]; 
    cb_func("param1",2); 

    cb_func=callback_functions[1]; 
    cb_func("param1",2,3.333); 

    cb_func=callback_functions[2]; 
    cb_func("param1",2,"param3"); 


    return 0; 
} 
niko: snippets $ gcc -g -Wl,--warn-common -ffunction-sections -fshort-enums -fdata-sections -Wall -Wextra -Wunreachable-code -Wmissing-prototypes -Wmissing-declarations -Wunused -Winline -Wstrict-prototypes -Wimplicit-function-declaration -Wformat -o varfuncs varfuncs.c 
varfuncs.c: In function ‘main’: 
varfuncs.c:22:3: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] 
    func1, 
^
varfuncs.c:22:3: note: (near initialization for ‘callback_functions[0]’) 
varfuncs.c:23:3: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] 
    func2, 
^
varfuncs.c:23:3: note: (near initialization for ‘callback_functions[1]’) 
varfuncs.c:24:3: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] 
    func3 
^
varfuncs.c:24:3: note: (near initialization for ‘callback_functions[2]’) 
niko: snippets $ 

빠른 참고 :

코드입니다 callback_functions는 [] 배열 (200 개) 요소 나 아마 같은 큰 것, 그래서 함수 포인터 배열에 저장해야합니다. 참고로 처음 두 개의 매개 변수 만 고정되고 이후에는 다를 수 있습니다. 그래서 거대한 switch() 문이 될 것이므로 캐스팅을 피하고 싶었습니다.

답변

4

수 없습니다. 함수 서명은 호환되지 않으며 컴파일러는 사용자가 발에서 자신을 쏘지 못하게합니다.

가변 인수 함수 포인터를 사용하여 비 가변 함수를 가리킬 수 없습니다. 호출 사이트은 호출 된 함수가 예상하는 유형을 알아야합니다 (예 : 인수를 스택에 푸시하는 방법을 알아야 할 수도 있음).

, func2 등 모든 서명이 일치하는 가변적이어야하며 각자 특정 방식으로 va_args을 풀어야합니다.

+2

추가 인수를 전달하기 위해 3 번째 및 추가 매개 변수 (아마도'struct'에'포인터 '에 전달 된)에 void ('void *') 포인터를 사용하는 것이 좋습니다. 원하는 형식의 인수에 일부 형식 변환을 추가해야합니다. pthread가 인자를 스레드 본문 함수에 전달하는 방법을 설명합니다. – dvhh

+0

내가 할 수 없다면 컴파일러는 "경고"가 아니라 "오류"를보고해야합니다. 그것에 대하여 너는 확신하니? – Nulik

+0

@dvhh 좋은 아이디어! 나는 매우 긴 매개 변수 목록을 가지지 않기 때문에 (void *)를 사용할 것이라고 생각하지만, 수십 개의 typedef가 있으므로 void (*)가 작동합니다. 유일한 단점은, 사용하지 않는 매개 변수를 채우려면 NULL을 전달해야합니다. 답변으로 의견을 게시 할 수 있습니다. 매우 좋은 아이디어라고 생각합니다. – Nulik

관련 문제