The proper way is to cast it to another pointer type. Converting a void* to an int is non-portable way that may work or may not! If you need to keep the returned address, just keep it as void*.
On most platforms pointers and longs are the same size, but ints and pointers often are not the same size on 64bit platforms. If you convert (void*) to (long) no precision is lost, then by assigning the (long) to an (int), it properly truncates the number to fit.
Casting a pointer to void* and back is valid use of reinterpret_cast<>. So you could do this:
pthread_create(&thread, NULL, myFcn, new int(5)); // implicit cast to void* from int*
Then in myFcn:
void* myFcn(void* arg)
{
int* data = reinterpret_cast<int*>(arg);
int x = *data;
delete data;
Note: As sbi points out this would require a change on the OP call to create the thread.
What I am trying to emphasis that conversion from int to pointer and back again can be frough with problems as you move from platform to platform. BUT converting a pointer to void* and back again is well supported (everywhere).
Thus as a result it may be less error prone to generate a pointer dynamcially and use that.
Remembering to delete the pointer after use so that we don't leak.
then the void* arriving inside of myFcn has the value of the int you put into it. So you know you can cast it back like this
int myData = reinterpret_cast<int>(arg);
even though the compiler doesn't know you only ever pass myFcn to pthread_create in conjunction with an integer.
Edit:
As was pointed out by Martin, this presumes that sizeof(void*)>=sizeof(int). If your code has the chance to ever be ported to some platform where this doesn't hold, this won't work.
There's no proper way to cast this to int in general case. C99 standard library provides intptr_t and uintptr_t typedefs, which are supposed to be used whenever the need to perform such a cast comes about. If your standard library (even if it is not C99) happens to provide these types - use them. If not, check the pointer size on your platform, define these typedefs accordingly yourself and use them.
//new_fd is a int
pthread_create(&threads[threads_in_use] , NULL, accept_request, (void*)((long)new_fd));
//inside the method I then have
int client;
client = (long)new_fd;
long guarantees a pointer size on Linux on any machine. Windows has 32 bit long only on 64 bit as well. Therefore, you need to change it to long long instead of long in windows for 64 bits.
So reinterpret_cast has casted it to long type and then static_cast safely casts long to int, if you are ready do truncte the data.
Again, all of the answers above missed the point badly. The OP wanted to convert a pointer value to a int value, instead, most the answers, one way or the other, tried to wrongly convert the content of arg points to to a int value. And, most of these will not even work on gcc4.
The correct answer is, if one does not mind losing data precision,
int x = *((int*)(&arg));
This works on GCC4.
The best way is, if one can, do not do such casting, instead, if the same memory address has to be shared for pointer and int (e.g. for saving RAM), use union, and make sure, if the mem address is treated as an int only if you know it was last set as an int.
In my case, I was using a 32-bit value that needed to be passed to an OpenGL function as a void * representing an offset into a buffer.
You cannot just cast the 32-bit variable to a pointer, because that pointer on a 64-bit machine is twice as long. Half your pointer will be garbage. You need to pass an actual pointer.
This will get you a pointer from a 32 bit offset:
int32 nOffset = 762; // random offset
char * pOffset = NULL; // pointer to hold offset
pOffset += nOffset; // this will now hold the value of 762 correctly
glVertexAttribPointer(binding, nStep, glType, glTrueFalse, VertSize(), pOffset);
There is no "correct" way to store a 64-bit pointer in an 32-bit integer. The problem is not with casting, but with the target type loosing half of the pointer. The 32 remaining bits stored inside int are insufficient to reconstruct a pointer to the thread function. Most answers just try to extract 32 useless bits out of the argument.
As Ferruccio said, int must be replaced with intptr_t to make the program meaningful.