函数指针不兼容的指针类型 void (*)(void *) from void (my_type *)

bob*_*u10 1 c struct pointers function-pointers

我收到上述警告并理解它,但不知道如何解决它。我的代码在下面,但基本上我正在做的是将一个函数指针存储在一个结构中,并在我从 main 调用的另一个函数中初始化该结构。当我将代码与默认函数(即 free())一起使用时,代码似乎可以编译,但当我将它与下面的 test_func 函数一起使用时,代码似乎可以编译。想法?

结构:

  typedef struct my_struct {
  my_type **double_pointed;
  int num;
  void (*funcp)(void *data);
  } my_struct_t;
Run Code Online (Sandbox Code Playgroud)

初始化函数:

my_struct_t *init(int num, void (*my_funcp)(void *data)) {

    // unimportant code to the problem, but basically just some mallocs for the other data

  my_struct_t *my_str;
  my_str->funcp = my_funcp;

  return struct;
}
Run Code Online (Sandbox Code Playgroud)

我想指出的功能:

void desired_func(my_type *obj) {}
Run Code Online (Sandbox Code Playgroud)

我对 init 函数的调用:

init(5, desired_func);
Run Code Online (Sandbox Code Playgroud)

完整错误:

从“void (my_type *)”分配给“void (*)(void *)”的不兼容指针类型

在上面的 init 函数中的那一行:

my_struct_t *my_str;
my_str->funcp = my_funcp;
Run Code Online (Sandbox Code Playgroud)

San*_*ker 5

更改函数指针类型以匹配函数,即。:

void (*funcp)(my_type *data);
Run Code Online (Sandbox Code Playgroud)

如果您希望能够使用具有不同签名(例如,不同参数类型)的函数,您可以添加显式强制转换。例如 :

init(5, (void (*)(void*)) desired_func);
Run Code Online (Sandbox Code Playgroud)

请注意,任何时候需要通过函数指针调用desired_func函数(或任何其他签名与funcp函数指针不匹配的函数)时,函数指针都必须void (*)(my_type*)在调用之前转换回其原始类型(在这种情况下)函数,或者它调用未定义的行为。

另一个(更好)的替代方法是desired_func像这样改变定义:

void desired_func(void *vobj) {
    my_type* obj = vobj;
    /* rest of the code */
}
Run Code Online (Sandbox Code Playgroud)

请注意,在调用时desired_func(通过函数指针或直接调用),其地址作为参数传递的对象的类型需要是my_type,或者obj在函数内部取消引用(如果对齐方式不同,甚至转换本身)将调用未定义的行为。

转换时处理潜在未定义行为的额外复杂性(如上所述)意味着我建议不要进行转换 - 需要这样的转换可能表明您的设计存在问题。IE。如果您多考虑一下您的要求,可能会有更好的解决方案。

  • 与“void *”之间的转换不需要强制转换,因此“my_type *obj = vobj;”就足够了。 (2认同)
  • 我认为最好在开始时放置更好的替代方案......除了在 `void *` 和其他指向对象类型之间转换时不需要强制转换。关于 UB,您可以触发警告并附加一些预处理器滥用:`#define desired_func(value) do { mytype *v = value; required_func(v); } while (0)`...很好的答案:) (2认同)