7_R3X
7_R3X

Reputation: 4370

Type-casting void* to long

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

Answers (2)

user3629249
user3629249

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

jforberg
jforberg

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

Related Questions