0

I'm trying to compile but getting the errors

error: expected expression before 'void'
warning: passing argument 3 of 'pthread_create' from incompatible pointer type [enabled by default] used [-Wunused-but-set-variable]

I type casted the struct to void* so it should work.

In the global variable section I have

struct threadArgs
{
    char** str;
    int length;
};
struct threadArgs arguments;

The lines around the error are here

arguments.str = str;
arguments.length = linesRead;
for(int i = 0; i < lettersInAlpha; i++)
    errCode[i] = pthread_create(&letter[i], NULL, &findMatch, (*void)&arguments);

the prototype for findMatch is void findMatch(char **str, const int length);

Also I think I'm doing the right thing by passing the arrays address, right?

Basically any code can be changed, so findMatch() can be modified as needed.

Celeritas
  • 14,489
  • 36
  • 113
  • 194

1 Answers1

1

Your function must be conforming to the requirements of pthreads as a valid thread-proc. Part of the compliance is the signature. it must be of the form void *func(void*). in other words your function must:

  • return void*
  • take a single void* parameter.

The argument address you provide at the end is passed to your thread proc, and you're responsible for unpacking your own parameters from there.

Trying to minimize the changes you need for findMatch, declare your thread function like this:

void * findMatch(void* pv)
{
    struct threadArgs * argsp = pv;
    char **str = argsp->str;
    const int length = argsp->length;

    // the rest of your code.

    return NULL;
}

Note: your code hints at something else that may be an issue. arguments is a global. This means that once you start a thread, if you modify arguments for preparation for the next thread, you have created a race condition where your modifications will potentially race with the initial thread's access of that memory. This isn't an issue in your code as-is, because you make no modifications to arguments from thread-to-thread creation. But if you ever do, consider allocating a separate arguments variable to be sent to each thread, so that thread "owns" it, and only it.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • Isn't that not a problem because the address passed to pthread_create() was created as a global variable? – Celeritas Oct 10 '13 at 00:56
  • @Celeritas you're absolutely right. I didn't see it hanging around up there. That introduces an entirely different problem, however, and I'll document it now. – WhozCraig Oct 10 '13 at 01:08
  • @Celeritas ok. thanks for catching that. I hope that makes sense now. Regardless, I hope you understand how the parameter passing to a `pthread_create` launched thread works. its just a pointer to "something", the details left to be settled between the thread-creator and the thread-proc. – WhozCraig Oct 10 '13 at 01:14
  • Just one small thing I'm concerned about: the compiler was still complaining `error: expected expression before 'void'` and when I removed the type cast `(*void)` from `&arguments` the error went away. Does this suggest there is a problem? – Celeritas Oct 10 '13 at 01:24
  • You never have to cast to, or from, `void*` in C. if you find yourself doing so, something is wrong. just `&arguments` should be sufficient. – WhozCraig Oct 10 '13 at 02:29
  • Oh ok the reason I thought so because I was following this as an example and they use `(void *)&args` http://stackoverflow.com/questions/1352749/multiple-arguments-to-function-called-by-pthread-create – Celeritas Oct 10 '13 at 02:52
  • @Celeritas in C, you don't have to cast to, or from, `void*`. It is one of the ways C and C++ differ. If `arguments` were `const`, you would have to cast, as the parameter pointer would be a non-const `void*`. In that case I wouldn't do it anyway, as removing a const-modifier is generally a bad idea. – WhozCraig Oct 10 '13 at 02:58