Reputation: 4370
Is it possible to directly type-caste a void pointer to long without causing a trouble? Below is a little code snippet I extracted from the code here (Example under Pthread Joining section of the page).
{
void *status;
long t;
rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t);
rc = pthread_join(thread[t], &status);
printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status);
}
As this manual page says that pthread_join() copies the exit status of the target thread (i.e., the value that the target thread supplied to pthread_exit()) into the location pointed to by *retval(*status in this case). But in the program I mentioned in question, status doesn't point to any location. Then how is it that the program still works?
And secondly,as far as my knowledge is concerned, status cannot hold a long value then how does typecasting status gives us a value which is long and not an address?
Upvotes: 2
Views: 3892
Reputation: 16540
this line:
rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t);
is not correct.
Suggest using:
rc = pthread_create(&thread[t], &attr, BusyWork, (void *)&t);
Then the 'problem' disappears
Note: in the Busywork()
function get the actual value back by:
long myVar = *parmVoidPtr;
Upvotes: 0
Reputation: 6752
Quick answer: No, use intptr_t
Long answer: long is not guaranteed to fit into a void *. On some systems (notably 64-bit Intel Linux machines) it will work since void * and long are both 64-bit quantities and the Intel processor has no other type differences. On other machines such as 32-bit Intel Linux it will not work since long is 64-bit and void * 32-bit on those machines. More exotic machines have different properties.
The standard type that supports int <-> pointer conversions is intptr_t, found in stdint.h. According to the POSIX Programmer's Manual:
The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to a pointer to void, and the result will compare equal to the original pointer: intptr_t
So intptr_t is a signed integer type of unspecified length which is guaranteed to support conversions from and to void *. There is also unsigned uintptr_t.
Here is the definition of intptr_t in glibc. As you can see, on 64-bit machines intptr_t and long are indeed the same type.
Upvotes: 3