【问题标题】:Passing a function with void pointer as argument gives warning使用 void 指针作为参数传递函数会发出警告
【发布时间】:2019-04-29 08:58:36
【问题描述】:

我实现了一个队列并想要一个打印其元素的函数,而不管其类型如何。所以我做了一个函数printQueue如下:

void printQueue(queue_t *queue, void (*f)(void *)) {
  node_t *node = (*queue).front;
  while(node != NULL) {
    (*f)(node->item);
    puts("");
    node = (*node).next;
  }
}

这个想法是它将接收队列,以及一个从队列中打印元素的函数(队列被实现为能够容纳任何类型的元素)。所以这个函数将迭代队列并调用该函数来打印它的每个元素。

然后我创建了一个函数来打印 int 数组,这些数组在它的第一个元素中包含自己的大小,如下所示:

void printSpecialIntArray(int *array) {
  int i;
  for(i=0; i<array[0]; i++) {
    printf("%d ", array[i]);
  }
}

但是,如果我用这种数组初始化一个队列说 Q 并调用 printQueue(Q, printSpecialIntArray) 它似乎按预期工作,但我收到一个警告:

warning: passing argument 2 of ‘printQueue’ from incompatible pointer type [-Wincompatible-pointer-types]
   printQueue(Q, printSpecialIntArray);
                   ^~~~~~~~~~~~
In file included from main.c:3:0:
queue.c:32:6: note: expected ‘void (*)(void *)’ but argument is of type ‘void (*)(int *)’
 void printQueue(queue_t *queue, void (*f)(void *)) {

为什么会出现此警告,如何解决?有没有更清洁的方法来做到这一点?

另外,如果您想知道,我正在使用一个具有自己大小的数组作为元素,因为我正在实现一个进程模拟器,而那些“特殊 int 数组”实际上应该代表一个进程。如果您知道一种更清洁的方法,如果您在回答/评论中包括在内,我也将不胜感激。

【问题讨论】:

  • 如果printQueue 应该采用void (*f)(int*),为什么您将其定义为采用void (*f)(void *)
  • 错误信息很清楚。
  • @Blaze 不一定。在这种情况下,如果我使用int* 的队列,它应该接受它。但是,例如,如果我要使用 char * 的队列并创建一个函数来打印它,我希望这也是可能的。我使用了void *,因为我认为这可以让我使用指向任何类型数据的指针。

标签: c parameter-passing warnings


【解决方案1】:

错误消息非常直接。函数void printQueue(queue_t *queue, void (*f)(void *)) 期望f 是一个指向返回void 并只接受一个参数的函数的指针,它的类型应该是void*。函数printSpecialIntArray 不满足这个要求,因为它的参数是int*

一种解决方案是更改f,使其将int* 作为参数而不是void*。另一种解决方案是重写printSpecialIntArray

void printSpecialIntArray(void *a) {
  int *array = (int*) a;
  int i;
  for(i=0; i<array[0]; i++) {
    printf("%d ", array[i]);
  }
}

注意:

即使 void 指针可以安全地提升为 int 指针,函数 f 仍然需要是一个以 void 指针作为参数的函数。问题不在于参数,而在于函数声明本身。

【讨论】:

    【解决方案2】:

    您的函数签名不匹配。 您需要提供预期的签名并根据您的需要转换指针:

    void printSpecialIntArray(void *arr) {
      int array = (int *)arr;
      int i;
      for(i=0; i<array[0]; i++) {
        printf("%d ", array[i]);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-29
      • 2021-04-08
      • 2018-08-25
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 2012-11-28
      • 2020-11-08
      相关资源
      最近更新 更多