goutham goutham - 5 months ago 14
Linux Question

conversion from int to void * is possible?

I am learning multithreading concept from http://www.tutorialspoint.com/cplusplus/cpp_multithreading.htm.
i had come across this doubt..here in below example program he is trying to convert int to void*..
i think converting int to void* is illegal,int address should be converted to void *..

I mentioned code belw please have a look.

Example 1:-

#include <iostream>
#include <cstdlib>
#include <pthread.h>

using namespace std;

#define NUM_THREADS 5

void *PrintHello(void *threadid)
{

long tid;
tid = (long)threadid;
cout << "Hello World! Thread ID, " << tid << endl;
pthread_exit(NULL);
}

int main ()
{
pthread_t threads[NUM_THREADS];
int rc;
int i;
for( i=0; i < NUM_THREADS; i++ ){
cout << "main() : creating thread, " << i << endl;
rc = pthread_create(&threads[i], NULL,
PrintHello, (void *)i);//this was the line where he is converting int to void *,i feel this is correct (void *)&i but result is not as expected if i change it
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}


Example 2:-

#include <iostream>
#include <cstdlib>
#include <pthread.h>

using namespace std;

#define NUM_THREADS 5

struct thread_data{
int thread_id;
char *message;
};

void *PrintHello(void *threadarg)
{
struct thread_data *my_data;

my_data = (struct thread_data *) threadarg;

cout << "Thread ID : " << my_data->thread_id ;
cout << " Message : " << my_data->message << endl;

pthread_exit(NULL);
}

int main ()
{
pthread_t threads[NUM_THREADS];
struct thread_data td[NUM_THREADS];
int rc;
int i;

for( i=0; i < NUM_THREADS; i++ ){
cout <<"main() : creating thread, " << i << endl;
td[i].thread_id = i;
td[i].message = "This is message";
rc = pthread_create(&threads[i], NULL,
PrintHello, (void *)&td[i]);//in this he is typecasting by thread_data address to void *
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}


can you explain the difference why he is not typecasting int address variable to void *

Answer

You are right that in general it might not work, as we have few guarantees about the relative sizes of int and void*. However, on systems that succeed in implementing pthread, a void* will be large enough to hold the int.

The reason for doing so, is the interface of pthread_create which takes a void* and passes that to the thread function when that starts. The idea is likely that this parameter should be a pointer to some data structure. However (again), when the data is as small as an int, you can cheat and pass it directly.

Note that the PrintHello function immediately casts the parameter back to its original type (which must be agreed on).

Also, you don't have to cast a data pointer to void*, as that conversion is implicit. You do have to use a cast to get the original type back though.