How should I handle "cast from ‘void*’ to ‘int’ loses precision" when compiling 32-bit code on 64-bit machine? How should I handle "cast from ‘void*’ to ‘int’ loses precision" when compiling 32-bit code on 64-bit machine? linux linux

How should I handle "cast from ‘void*’ to ‘int’ loses precision" when compiling 32-bit code on 64-bit machine?


The issue is that, in 32bits, an int (which is a 32bit integer) will hold a pointer value.

When you move to 64bit, you can no longer store a pointer in an int - it isn't large enough to hold a 64bit pointer. The intptr_t type is designed for this.


Your code is broken. It won't become any less broken by ignoring the warnings the compiler gives you.

What do you think will happen when you try to store a 64-bit wide pointer into a 32-bit integer? Half your data will get thrown away. I can't imagine many cases where that is the correct thing to do, or where it won't cause errors.

Fix your code. Or stay on the 32-bit platform that the code currently works on.

If your compiler defines intptr_t or uintptr_t, use those, as they are integer types guaranteed to be large enough to store a pointer.

If those types are not available, size_t or ptrdiff_t are also large enough to hold a pointer on most (not all) platforms. Or use long (is typically 64-bit on 64-bit platforms on the GCC compiler) or long long (a C99 types which most, but not all compilers, support in C++), or some other implementation-defined integral type that is at least 64 bits wide on a 64-bit platform.


My guess is OP's situation is a void* is being used as general storage for an int, where the void* is larger than the int. So eg:

int i = 123;void *v = (void*)i;    // 64bit void* being (ab)used to store 32bit value[..]int i2 = (int)v;       // we want our 32bits of the 64bit void* back

Compiler doesn't like that last line.

I'm not going to weigh in on whether it's right or wrong to abuse a void* this way. If you really want to fool the compiler, the following technique seems to work, even with -Wall:

int i2 = *((int*)&v);

Here it takes the address of v, converts the address to a pointer of the datatype you want, then follows the pointer.