摆脱不兼容的指针警告

时间:2016-09-20 01:27:13

标签: c

我在编译代码时收到此警告:

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()语句。

1 个答案:

答案 0 :(得分:4)

你不能。您的功能签名不兼容,并且编译器阻止您自己射击。

您不能使用可变参数函数指针指向非可变函数。 调用站点必须知道调用函数所期望的类型(例如,它可能需要知道如何将参数推送到堆栈中)。

如果你真的想这样做,你应该使用func1func2等所有变量匹配的签名,并且每个都应该以任何特定的方式解包va_args想。