【问题标题】:Warning: Assignment from Incompatible Pointer Type [enabled by default] while assigning Function Address to Function Pointer警告:在将函数地址分配给函数指针时,从不兼容的指针类型分配[默认启用]
【发布时间】:2014-12-24 05:58:58
【问题描述】:

我正在尝试使用函数指针实现一个简单的交换函数,但是当我将函数的地址分配给函数指针时:

`pointersTofunctionB.c:14:6:warning: 来自不兼容指针类型的赋值 [默认启用]。

这是我的代码:

#include <stdio.h>
void intSwap(int *a,int *b);
void charSwap(char *a,char *b);
void (*swap)(void*,void*);
int main(int argc, char const *argv[])
{
    int a=20,b=15;
    char c='j',d='H';
    swap=&intSwap;// warning here
    swap(&a,&b);
    printf("%d %d\n",a,b);
    swap=&charSwap;// warning here also
    swap(&c,&d);
    printf("%c %c\n",c,d ); 
    return 0;
}


void intSwap(int *a,int *b)
{
    *a=*a+*b;
    *b=*a-*b;
    *a=*a-*b;
}
void charSwap(char *a,char *b)
{
    char temp;
    temp=*a;
    *a=*b;
    *b=temp;
}

我该如何解决这个警告?

【问题讨论】:

    标签: c function pointers function-pointers


    【解决方案1】:

    由于以下 C 标准的引用而出现警告

    6.3.2.3 指针

    8 指向一种类型的函数的指针可以转换为指向 另一种类型的功能并再次返回;结果应比较 等于原来的指针。 如果使用转换后的指针 调用类型与引用类型不兼容的函数, 行为未定义。

    两个函数应该兼容,它们的参数应该有兼容的类型

    6.7.6.3 函数声明符(包括原型)

    15 对于要兼容的两种函数类型,两者都应指定 兼容的返回类型。146) 此外,参数类型列表,如果 两者都存在,应在参数数量和使用中达成一致 省略号终止符; 对应的参数应有 兼容的类型。

    在您的函数中,参数被声明为指针。为了使它们(指针)兼容,它们应该是指向兼容类型的指针

    6.7.6.1 指针声明符

    2 对于要兼容的两种指针类型,两者应具有相同的限定,并且都都应是指向兼容类型的指针。

    但是一方面是 int 或 char 类型,另一方面是 void 类型是不兼容的类型。

    您可以通过以下方式定义您的函数

    void intSwap( void *a, void *b )
    {
        int *x = a;
        int *y = b;
    
        *x = *x + *y;
        *y = *x - *y;
        *x = *x - *y;
    }
    
    void charSwap( void *a, void *b )
    {
        char *c1 = a;
        char *c2 = b;
        char temp = *c1;
    
        *c1 = *c2;
        *c2 = temp;
    }
    

    【讨论】:

    • 你可以显式转换:swap = (void ( * )(void*, void*))intSwap;由于 sizeof(void*) == sizeof(int*) 这应该是完全安全和可移植的。
    • 如果您想在其他地方直接涉及 intSwap,这将有利于保持类型安全......
    【解决方案2】:

    你需要改变

     swap=&intSwap;
    

     swap=intSwap;
    

    swap=&amp;charSwap; 也一样。

    同样,您的函数签名与函数指针签名不匹配。

    你的功能是

    void intSwap(int *a,int *b);
    

    返回类型为void,两个输入参数int *,而你的函数指针签名是

    void (*swap)(void*,void*);
    

    这需要两个void *s。 void charSwap 函数也一样。

    要么你必须改变函数签名,要么你必须使用不同的函数指针原型。否则,行为未定义。 [如弗拉德的回答中所述]。

    【讨论】:

    • &amp;intSwap 本身的计算结果与 intSwap 相同。与符号是否存在无关紧要。
    • @MichaelBurr 你说得对,先生,他们的评价都是一样的。不过我认为推荐写成swap=intSwap;。请纠正我我错了。
    • 我个人对这两种方式都没有强烈的感觉,我不确定其他人是否建议将&符号关闭。
    【解决方案3】:
    #include<stdio.h>
    using namespace std;
    
    void intSwap(int *a,int *b);
    void charSwap(char *a,char *b);
    void (*swap)(int*,int*);
    void (*swap1)(char*,char*);
    int main()
    {
        int a=20,b=15;
        char c='j',d='H';
        swap=&intSwap;// warning here
        swap(&a,&b);
        printf("%d %d\n",a,b);
        swap1=&charSwap;// warning here also
        swap1(&c,&d);
        printf("%c %c\n",c,d ); 
        return 0;
    }
    
    
    void intSwap(int *a,int *b)
    {
        *a=*a+*b;
        *b=*a-*b;
        *a=*a-*b;
    }
    void charSwap(char *a,char *b)
    {
        char temp;
        temp=*a;
        *a=*b;
        *b=temp;
    }
    
    **If you want you can use like it......**
    

    【讨论】:

    • 而不是像你提到的那样做,我可以简单地使用相应的函数名称本身。我想展示函数指针的使用,但是你提到的修改还不够。
    • using namespace std;?问题是关于 C,而不是 C++。
    【解决方案4】:

    要删除警告,请编写此重载代码:

    void (*swap)(int *,int*);
    
    void (*swap)(char *,char*);
    

    【讨论】:

    • 这是什么?能详细点吗?
    猜你喜欢
    • 2014-10-10
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多