1

Looking at the man page for pthread_create(...), I see the definition is as follows...

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

My first question is in pthread_create while passing argument 3; am I casting the address of function name or just the function name? For me it seems to produce the same results... so what is the difference between these?

(void *)&function_name
(void *)function_name

My second question is in pthread_create while passing argument 4, should we always give the address of the args variable like,

(void *) &variable

or can we directly pass the value like

(void *)variable

Thanks.

dovedevic
  • 673
  • 2
  • 14
  • 33
user1762571
  • 1,888
  • 7
  • 28
  • 47
  • Function and array address will be get with or without &. [Function pointers and address of a function](http://stackoverflow.com/questions/9552663/function-pointers-and-address-of-a-function) – Li-chih Wu Jul 10 '13 at 02:23
  • Re (1) func name is already the address of a function taking and returning a void ptr. Casting it to a void ptr may not do harm but I don't think it is doing you any good either. In my mind both the options you present are technically wrong. – Duck Jul 10 '13 at 02:31
  • @ Duck Can you please tell what is wrong here.? – user1762571 Jul 10 '13 at 02:32
  • The 3rd parm is a pointer to a function that takes a void ptr argument and returns a void ptr result. That's exactly what function_name is already. In both examples you are casting that ptr type to a void ptr for no reason. – Duck Jul 10 '13 at 02:48
  • @ Duck But when i just gave the function name as 3rd argument, i am getting this error......... pthread1.c:12:3: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [enabled by default] /usr/include/pthread.h:225:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘void (*)(void)’ – user1762571 Jul 10 '13 at 02:57
  • Because your function is wrong. It takes and returns pointers to void *not* void. – Duck Jul 10 '13 at 03:17
  • @ Duck Can you please explain in detail about this. I really couldn't understand this void thing. – user1762571 Jul 10 '13 at 04:02
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33206/discussion-between-user1762571-and-duck) – user1762571 Jul 10 '13 at 14:41

2 Answers2

4

Continued from the comments above...

(1) The pthread_create start function (3rd parameter) must have a signature of

void *(*start_routine) (void *)

that is, a function that takes a void pointer and returns a void pointer. For example:

void* myfunc(void *)

You are getting compile errors because your start function probably (and incorrectly) looks like this:

void myfunc(void)

in other words a function that takes no parameters and returns no result. You got around this compiler error by casting myfunc to a pointer to void but it is unnecessary and wrong. Your real problem is that your start function "myfunc" has the wrong signature.

(2) It seems you are hung up on void and pointers to void. There several good answers here on this including this. Basically a pointer to void is a generic pointer that can point to any type.

pthread_create is itself an excellent example of the use of void ptrs. Because there is no way for a start function to know what kind of data a developer wants to pass into (and return) from the function they use a void ptr that can point to any type. It is up to the developer of the start function to then cast the void ptr to appropriate type he actually passed before using whatever the void ptr points to. So now the start function can process a ptr that may in actually point to an int, a double, an array, a structure, or whatever.

In your case you are turning a pointer to a function with a specific signature into a pointer to anything. This may satisfy the compiler because it assumes you know what you are doing. But in this instance you don't because you are papering over the real error which is that the signature of your start function is wrong.

Community
  • 1
  • 1
Duck
  • 26,924
  • 5
  • 64
  • 92
  • @ Duck. Thanks.got it. I will tell you my understanding. please let me know whether it is correct or not. The function prototype should match this format[void *(*start_routine) (void *)]. If not, we should typecast it accordingly and give as an argument to pthread_create. – user1762571 Jul 11 '13 at 17:57
  • @ Duck. I have another doubt also.. In this link https://computing.llnl.gov/tutorials/pthreads/samples/hello.c in the statement rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); the coder has just passed a variable as 4th argument without passing address of that variable. Is this code correct?? If yes how can we cast a variable to void *. – user1762571 Jul 11 '13 at 18:11
  • On the 1st, no, I don't think you understand. The start function *has* to have that signature. That's the *one and only* acceptable sig. You *can not* cast your way out of it. And there is no point. As is, it is a func that takes anything and returns anything. It couldn't be more flexible. I'll get to your other Q in a bit when I have time. – Duck Jul 11 '13 at 18:46
  • @ Duck - So my function MUST be of this signature [void *(*start_routine) (void *)] and in pthread_create it can be like this pthread_create(threads, NULL, start_routine, NULL); Here the third argument is correct right? or any casting should be done?? – user1762571 Jul 11 '13 at 19:38
  • @ Duck Thanks. Please explain me about my second question when you have time. – user1762571 Jul 11 '13 at 20:11
  • @user1762571 On your 2nd Q, I think you would do better to ask a separate question under just the C tag and leave pthreads out it as you will get more responses. It is really a question about how to pass values to functions with void ptrs. While I can answer your questions piece meal I am struggling to come up with the comprehensive explanation you deserve. I am sure the C language lawyers are prepared to explain more thoughtfully and concisely. Submit your question using examples in plain platform neutral C for the best results and drill down on the answers until you understand. – Duck Jul 11 '13 at 20:43
  • @ Duck. I will post it as a separate question. Thank you so much Duck – user1762571 Jul 11 '13 at 23:35
1

Function and array address will be get with or without &.
But other varibles won't, you should still use (void*)&variable.

FYI
Function pointers and address of a function

Community
  • 1
  • 1
Li-chih Wu
  • 1,002
  • 1
  • 11
  • 19
  • .@ Li-chih wu. Thanks. For variable casting, i am confused after seeing the code i found in this below link with name (Example Code - Pthread Creation and Termination.). Here they are casting a variable to (void *) https://computing.llnl.gov/tutorials/pthreads/#Designing – user1762571 Jul 10 '13 at 02:37
  • pthread_create's 4th argument is (void*), so even if you want to pass a int, you should still still cast it to (void*), then cast it back to int in start_routine. – Li-chih Wu Jul 10 '13 at 05:21
  • depend on system, pointer would be a double word or even 64 bits value, mostly you can only cast a numeric value to and back safely. – Li-chih Wu Jul 10 '13 at 07:39