C警告:传递不兼容的指针类型

4
我不断试图编译代码,但是出现了错误。错误如下:
warning: incompatible pointer types passing
  'void *(threadData *)' to parameter of type 'void * (*)(void *)'
  [-Wincompatible-pointer-types]
        pthread_create(&threads[id], NULL, start,&data[id]);

我想把一个结构体传给函数void * start(threadData* data),但我一直被这个问题困扰。你有什么想法吗?

第一个答案解释了如何解决你的问题。 - 2501
1个回答

7

它在抱怨线程函数(绑定到pthread_create的第三个参数)的问题,您可以修改它以接受void *参数,然后在执行任何操作之前将其强制转换回来:

void *start (void *voidData) {
    threadData *data = voidData;
    // rest of code here, using correctly typed data.

你也可以选择强制将数据指针(第四个参数)转换为期望的类型:

(void*)(&(data[id]))

但我认为这并不必要,因为 void * 应该可以自由地转换成和其他大多数指针类型之间。


您可以在这个小的、完整的程序中看到问题:

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

struct sData { char text[100]; };

void *start (struct sData *data) {
        printf ("[%s]\n", data->text);
}

int main (void) {
        struct sData sd;
        pthread_t tid;
        int rc;

        strcpy (sd.text, "paxdiablo");
        rc = pthread_create (&tid, NULL, start, &sd);
        pthread_join (tid, NULL);

        return 0;
}

编译时,您会看到:

prog.c: In function 'main':
prog.c:20:2: warning: passing argument 3 of 'pthread_create' from
             incompatible pointer type [enabled by default]
             In file included from prog.c:3:0:
                 /usr/include/pthread.h:225:12: note: expected
                     'void * (*)(void *)' but argument is of type
                     'void * (*)(struct sData *)'

请记住,这只是一个警告,而不是错误,但是如果您想让您的代码编译干净,请努力摆脱它。按照本答案顶部提到的更改(除数据参数转换外),您将得到以下线程函数:
void *start (void *voidData) {
        struct sData *data = voidData;
        printf ("[%s]\n", data->text);
}

这段代码编译没有警告,并且可以正常运行。


@paxidiablo 嗯,我尝试了那个确切的方法,但它仍然在第三个参数 start 上出现错误。 - jgabb
@jgabb,那么您需要在问题中添加更多信息。使用void *start(void*)使其成为_确切_的正确类型,因此我认为您可能在某个地方打错了字,或者仍然在原型中使用旧的声明之类的东西。如果错误消息相同,则表示您尚未更改代码(因为它仍然提到threadData*)。 - paxdiablo
你是正确的 =) 谢谢! - jgabb
这会在我尝试访问结构中的数据时保留它吗?例如,我可以执行data->example吗? - jgabb
@jgabb:是的,你需要将它转换为void*,然后作为参数传递给pthread_create函数。该函数会将其原样传递给线程函数,然后在第一行将其转换回来。一旦线程函数完成了这个步骤,它就可以像真正的结构体一样访问它:data->somethingOrOther - paxdiablo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接