使用void指针作为参数传递函数会发出警告

问题描述 投票:4回答:2

我实现了一个队列,并想要一个打印其元素的函数,无论其类型如何。所以我创建了一个函数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数组”实际上应该代表一个进程。如果你知道一种更清洁的方法,如果你在答案/评论中加入,我也将不胜感激。

c parameter-passing warnings
2个回答
3
投票

错误消息非常简单。函数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指针作为参数的函数。这不是问题的论点,而是函数声明本身。


3
投票

您的功能签名不匹配。您需要提供预期的签名并根据您的需要投射指针:

void printSpecialIntArray(void *arr) {
  int array = (int *)arr;
  int i;
  for(i=0; i<array[0]; i++) {
    printf("%d ", array[i]);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.