Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cast an integer to void pointer?

Tags:

While working with Threads in C, I'm facing the warning

"warning: cast to pointer from integer of different size"

The code is as follows

#include<stdio.h> #include<sys/types.h> #include<stdlib.h> #include<pthread.h> void *print(void *id) {  int a=10;  printf("My thread id is %ld\n",pthread_self());  printf("Thread %d is executing\n",id);  return (void *) 42; }  int main() {  pthread_t th[5];  int t;  int i;  int status;  void *ret;  for(i=0;i<5;i++)  {    status=pthread_create(&th[i],NULL,print,(void *)i); //Getting warning at this line    if(status)    {     printf("Error creating threads\n");     exit(0);    }    pthread_join(th[i],&ret);    printf("--->%d\n",(int *)ret);  }  pthread_exit(NULL); } 

Can anybody explain how to pass an integer to a function which receives (void * ) as a parameter?

like image 231
Dinesh Avatar asked Dec 13 '11 10:12

Dinesh


People also ask

Can you cast int to void?

"what happen when typcating normal variable to void* or any pointer variable?" Implementation-dependent. Note that it's not guaranteed that casting an int to void* and back yields the original value (though usually, it does).

How do I assign an int to a void pointer?

Now, we want to assign the void pointer to integer pointer, in order to do this, we need to apply the cast operator, i.e., (int *) to the void pointer variable. This cast operator tells the compiler which type of value void pointer is holding.

Can you cast any pointer to a void pointer?

Any pointer to an object, optionally type-qualified, can be converted to void* , keeping the same const or volatile qualifications.

What happens when you cast int to pointer?

A cast from integer to pointer discards most-significant bits if the pointer representation is smaller than the integer type, extends according to the signedness of the integer type if the pointer representation is larger than the integer type, otherwise the bits are unchanged.


1 Answers

This is a fine way to pass integers to new pthreads, if that is what you need. You just need to suppress the warning, and this will do it:

#include <stdint.h>  void *threadfunc(void *param) {     int id = (intptr_t) param;     ... }  int i, r; r = pthread_create(&thread, NULL, threadfunc, (void *) (intptr_t) i); 

Discussion

This may offend your sensibilities, but it's very short and has no race conditions (as you'd have if you used &i). No sense in writing a few dozen lines of extra code just to get a bunch of numbered threads.

Data races

Here is a bad version with a data race:

#include <pthread.h> #include <stdio.h>  #define N 10  void *thread_func(void *arg) {     int *ptr = arg;     // Has *ptr changed by the time we get here?  Maybe!     printf("Arg = %d\n", *ptr);     return NULL; }  int main() {     int i;     pthread_t threads[N];     for (i = 0; i < N; i++) {         // NO NO NO NO this is bad!         pthread_create(&threads[i], NULL, thread_func, &i);     }     for (i = 0; i < N; i++) {         pthread_join(threads[i], NULL);     }     return 0; } 

Now, what happens when I run it with the thread sanitizer?

(Also, check out how it prints "5" twice...)

 ================== WARNING: ThreadSanitizer: data race (pid=20494)   Read of size 4 at 0x7ffc95a834ec by thread T1:     #0 thread_func /home/depp/test.c:9 (a.out+0x000000000a8c)     #1 <null> <null> (libtsan.so.0+0x000000023519)    Previous write of size 4 at 0x7ffc95a834ec by main thread:     #0 main /home/depp/test.c:17 (a.out+0x000000000b3a)    Location is stack of main thread.    Thread T1 (tid=20496, running) created by main thread at:     #0 pthread_create <null> (libtsan.so.0+0x0000000273d4)     #1 main /home/depp/test.c:18 (a.out+0x000000000b1c)  SUMMARY: ThreadSanitizer: data race /home/depp/test.c:9 thread_func ================== Arg = 1 Arg = 2 Arg = 3 Arg = 4 Arg = 5 Arg = 6 Arg = 7 Arg = 8 Arg = 9 Arg = 5 ThreadSanitizer: reported 1 warnings 
like image 74
Dietrich Epp Avatar answered Jan 22 '23 22:01

Dietrich Epp