what does it mean to convert int to void* or vice versa?

Mathai picture Mathai · Dec 23, 2011 · Viewed 26.5k times · Source

What does it mean to convert an integer value to a void* or viceversa from a memory point of view? My understanding is void* is an address to a block of memory of unspecified length.
This seems to be something like comparing apple with oranges.

int myval = 5;
void* ptr = (void*)myval;
printf("%d",(int)ptr);

I realized that I should have given the exact context where this is used.

int main(int argc, char* argv[]) {
long       thread;  /* Use long in case of a 64-bit system */
pthread_t* thread_handles; 

/* Get number of threads from command line */
if (argc != 2) Usage(argv[0]);
thread_count = strtol(argv[1], NULL, 10);  
if (thread_count <= 0 || thread_count > MAX_THREADS) Usage(argv[0]);

thread_handles = malloc (thread_count*sizeof(pthread_t)); 

for (thread = 0; thread < thread_count; thread++)  
  pthread_create(&thread_handles[thread], NULL, Hello, (void*) thread);  

printf("Hello from the main thread\n");

for (thread = 0; thread < thread_count; thread++) 
  pthread_join(thread_handles[thread], NULL); 

free(thread_handles);
return 0;
}  /* main */

/*-------------------------------------------------------------------*/
void *Hello(void* rank) {
long my_rank = (long) rank;  /* Use long in case of 64-bit system */ 

printf("Hello from thread %ld of %d\n", my_rank, thread_count);

return NULL;
}  /* Hello */

This code is from Peter Pachecho's book on Parallel programming.

Answer

bobbymcr picture bobbymcr · Dec 23, 2011

Casting int to void * is rather meaningless and should not be done as you would be attempting to cast a non-pointer to a pointer. Quoting the C99 standard, section 6.3.2.3 item 5:

An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.

You could cast int * to void * (any pointer is convertible to void * which you can think of like the "base type" of all pointers).

Casting void * to int is not portable and may be completely wrong depending on the platform you use (e.g. void * maybe 64 bits wide and int may only be 32 bits). Quoting the C99 standard again, section 6.3.2.3 item 6:

Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.

To solve this, some platforms provide uintptr_t which allows you to treat a pointer as a numeric value of the proper width.