传递带有 void 指针作为参数的函数会发出警告
Passing a function with void pointer as argument gives warning
我实现了一个队列并想要一个函数来打印它的元素,而不考虑类型。所以我做了一个函数 printQueue 如下:
void printQueue(queue_t *queue, void (*f)(void *)) {
node_t *node = (*queue).front;
while(node != NULL) {
(*f)(node->item);
puts("");
node = (*node).next;
}
}
这个想法是它将接收队列,以及一个从队列中打印元素的函数(队列被实现为能够容纳任何类型的元素)。所以这个函数将迭代队列并调用该函数来打印它的每个元素。
然后我创建了一个函数来打印整数数组,这些整数在其第一个元素中包含自己的大小,如下所示:
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 *)) {
为什么会出现此警告,如何解决?有更简洁的方法吗?
此外,如果您想知道,我使用一个数组作为元素,它有自己的大小,因为我正在实现一个流程模拟器,而那些 "Special int arrays" 实际上应该代表一个流程。如果您知道更简洁的方法来做到这一点,如果您将其包含在 answer/comment 中,我将不胜感激。
错误信息非常直接。函数 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 指针为参数的函数。问题不在于参数,而在于函数声明本身。
您的函数签名不匹配。
您需要提供预期的签名并根据需要投射指针:
void printSpecialIntArray(void *arr) {
int array = (int *)arr;
int i;
for(i=0; i<array[0]; i++) {
printf("%d ", array[i]);
}
}
我实现了一个队列并想要一个函数来打印它的元素,而不考虑类型。所以我做了一个函数 printQueue 如下:
void printQueue(queue_t *queue, void (*f)(void *)) {
node_t *node = (*queue).front;
while(node != NULL) {
(*f)(node->item);
puts("");
node = (*node).next;
}
}
这个想法是它将接收队列,以及一个从队列中打印元素的函数(队列被实现为能够容纳任何类型的元素)。所以这个函数将迭代队列并调用该函数来打印它的每个元素。
然后我创建了一个函数来打印整数数组,这些整数在其第一个元素中包含自己的大小,如下所示:
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 *)) {
为什么会出现此警告,如何解决?有更简洁的方法吗?
此外,如果您想知道,我使用一个数组作为元素,它有自己的大小,因为我正在实现一个流程模拟器,而那些 "Special int arrays" 实际上应该代表一个流程。如果您知道更简洁的方法来做到这一点,如果您将其包含在 answer/comment 中,我将不胜感激。
错误信息非常直接。函数 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 指针为参数的函数。问题不在于参数,而在于函数声明本身。
您的函数签名不匹配。 您需要提供预期的签名并根据需要投射指针:
void printSpecialIntArray(void *arr) {
int array = (int *)arr;
int i;
for(i=0; i<array[0]; i++) {
printf("%d ", array[i]);
}
}