doctopus
doctopus

Reputation: 5657

invalid conversion from ‘void* (*)(int (*)[2])’ to ‘void* (*)(void*) when trying to create a thread

I have a function that takes in a pair of piped file descriptors, reads numbers from one pipe, sorts them and writes back up to the parent through a 2nd pipe:

void *sort_chunk(int fds[][2]) {
    close(fds[DOWN][WRITE]);
    FILE* fddr = fdopen(fds[DOWN][READ], "r");
    char str[25];
    vector<long int> nums;

    // Read from parent and sort
    while (fgets(str, 20, fddr)) {
        string fstr = string(str);
        fstr.erase(fstr.length() - 1); // Remove trailing line return
        nums.push_back(stol(fstr));
    }
    fclose(fddr);

    bubblesort(nums);

    // Write back to parent
    close(fds[UP][READ]);
    FILE* fduw = fdopen(fds[UP][WRITE], "w");
    for (auto it = nums.begin(); it != nums.end(); it++) {
        fprintf(fduw, "%ld\n", *it);
    }
    fclose(fduw);
    exit(0);
}

I want to run this function in multiple child threads:

int fds[2][2];
pipe(fds[DOWN]);
pipe(fds[UP]);
pthread_create(&threads[i], NULL, sort_chunk, fds);

When I try to create the thread though, i get:

mysort.cc:139:38: error: invalid conversion from ‘void* (*)(int (*)[2])’ to ‘void* (*)(void*)’ [-fpermissive]
  139 |    pthread_create(&threads[i], NULL, sort_chunk, fds);
      |                                      ^~~~~~~~~~
      |                                      |
      |                                      void* (*)(int (*)[2])

Upvotes: 1

Views: 319

Answers (1)

Chris Dodd
Chris Dodd

Reputation: 126408

You need to fix your thread function to match the prototype that pthread_create expects:

void *sort_chunk(void *fds_) {
    int (*fds)[2] = fds_;   // works for C -- need an explicit cast for C++

The basic problem is that pthread_create expects a particular kind of function pointer with a single void * argument, so you can't safely call it any other way.

This works pretty well in C, but in C++, you'll need an explicit static_cast in the function, which is ugly. But for C++, you should probably be using std::thread anyways.

Upvotes: 3

Related Questions