使用右指针类型,不想使用void *进行强制转换

时间:2017-04-07 11:06:06

标签: c pointers callback

关于在我的下面的代码中使用正确的指针类型的问题。当我尝试在没有类型转换为void *的情况下初始化struct member函数时,我得到“initialization from incompatible pointer type” warnings

通过类型转换解决了问题,但我想使用右指针类型而不是转换为void *。

代码段:

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


typedef void (*set_id)(int id);
typedef void (*set_name)(char *name);

typedef struct prop {
    set_id *cb_setting_id;
    set_name *cb_setting_name;
}prop;


prop *setting_id(int id) {
    printf("ID:%d\n", id);  
}

prop *setting_name(char *in) {
    char *name;
    name = in;
    printf("Name:%s\n", name);
}
//Here type casted to void *, if not I get wrong pointer initalization 
//error
prop cb_prop = { .cb_setting_id=(void *)setting_id,     
                 .cb_setting_name=(void *)setting_name };

int main() {

    prop *cb_event; 
    cb_event = &cb_prop;

    cb_event->cb_setting_id = (void*)setting_id(2);
    cb_event->cb_setting_name = (void*)setting_name("/dev/ttyS1");

    return 0;   
}

没有类型转换,警告是:

struct_callback.c:25:33: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
     prop cb_prop = { .cb_setting_id=setting_id,
                                     ^
struct_callback.c:25:33: note: (near initialization for ‘cb_prop.cb_setting_id’)
struct_callback.c:32:26: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
  cb_event->cb_setting_id = setting_id(2);

3 个答案:

答案 0 :(得分:3)

检查例如set_id类型别名,它是一个指向函数的指针,该函数采用int参数而不返回任何内容。然后将其与setting_id函数进行比较,该函数采用int个参数, 返回指向prop 的指针。这两种类型不兼容。它变得更糟,因为声明setting_id函数返回指向prop但实际上没有返回任何内容的指针。

不仅如此,结构中的成员也是指向例如set_id表示cb_setting_id是指向函数的指针的指针。

稍后你做

cb_event->cb_setting_id = (void*)setting_id(2);

这是错误的,因为它调用 setting_id函数,并尝试将返回的值分配给cb_event->cb_setting_id。但setting_id函数不会返回任何内容。

第一个问题的解决方案是确保set_id类型和函数setting_id都相等。

第二个问题的解决方案是不声明成员是指针(因为它们已经是指针),或者通过将set_id更改为不是指针。

第三个问题的解决方案是删除那些行,因为前两个解决方案应该解决cb_prop结构的初始初始化。

答案 1 :(得分:1)

您指定的类型不兼容。

函数setting_id的类型为prop *(*)(int),但cb_setting_id字段的类型为void (*)(int)。 Simiarly for setting_name

您需要更改typedef以匹配该功能。此外,您的结构定义中有一个额外的间接级别,而不是您需要的。

typedef struct prop prop;

typedef prop *(*set_id)(int);
typedef prop *(*set_name)(char *);

struct prop {
    set_id cb_setting_id;
    set_name cb_setting_name;
};

答案 2 :(得分:0)

首先,您的函数指针typedef与实际函数不匹配,因为您使用不同的返回类型。但是在这里你隐藏了一个typedef背后的指针语法:

typedef void (*set_id)(int id);
typedef void (*set_name)(char *name);

因此,这些成为指向函数指针的指针:

set_id *cb_setting_id;
set_name *cb_setting_name;

这不是你想要的。只需将typedef更改为:

typedef prop* set_id (int id);
typedef prop* set_name (char *in);

请注意,不允许您向/ void*投射功能指针。 Void指针假设对象指针,而不是函数指针。因此,将函数指针转换为void*会导致指针转换无效。