C warning: incompatible pointer types passing

jgabb picture jgabb · Dec 4, 2014 · Viewed 29.4k times · Source

I keep getting an error when trying to compile my code. The error is as follows :

warning: incompatible pointer types passing
  'void *(threadData *)' to parameter of type 'void * (*)(void *)'
  [-Wincompatible-pointer-types]
        pthread_create(&threads[id], NULL, start,&data[id]);

I'm trying to pass a struct to the function, void * start(threadData* data), and this keeps throwing me off. Any ideas?

Answer

paxdiablo picture paxdiablo · Dec 4, 2014

It's complaining about the thread function (bound to the third parameter of pthread_create), you can modify that to take a void * argument and then cast it back before doing anything with it:

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

You may also opt to coerce the data pointer (fourth parameter) to the expected type:

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

but I don't think that's necessary since a void * is supposed to be freely convertible to and from most other pointers.


You can see the problem in this small yet complete program:

#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;
}

When compiling that, you see:

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 *)'

Keep in mind that it's just a warning, not an error but, if you want your code to compile cleanly, it's worth getting rid of. Making the changes mentioned at the top of this answer (bar the data parameter casting) gives you the following thread function:

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

This compiles without warnings, and runs just fine.