I'm dealing with some code that uses an external library in which you can pass values to callbacks via a void*
value.
Unfortunately, the previous person working on this code decided to just pass integers to these callbacks by casting an integer to a void pointer ((void*)val
).
I'm now working on cleaning up this mess, and I'm trying to determine the "proper" way to cast an integer to/from a void*
. Unfortunately, fixing the use of the void pointers is somewhat beyond the scope of the rework I'm able to do here.
Right now, I'm doing two casts to convert from/to a void pointer:
static_cast<int>(reinterpret_cast<intptr_t>(void_p))
and
reinterpret_cast<void *>(static_cast<intptr_t>(dat_val))
Since I'm on a 64 bit machine, casting directly ((int)void_p
) results in the error:
error: cast from 'void*' to 'int' loses precision [-fpermissive]
The original implementation did work with -fpermissive
, but I'm trying to get away from that for maintainability and bug-related issues, so I'm trying to do this "properly", e.g. c++ casts.
Casting directly to an int (static_cast<int>(void_p)
) fails (error: invalid static_cast from type 'void*' to type 'int'
). My understanding of reinterpret_cast
is that it basically just causes the compiler to treat the address of the value in question as the cast-to data-type without actually emitting any machine code, so casting an int
directly to a void*
would be a bad idea because the void*
is larger then the int
(4/8 bytes respectively).
I think using intptr_t
is the correct intermediate here, since it's guaranteed to be large enough to contain the integral value of the void*
, and once I have an integer value I can then truncate it without causing the compiler to complain.
Is this the correct, or even a sane approach given I'm stuck having to push data through a void pointer?
Yes, for the reason you mentioned that's the proper intermediate type. By now, if your implementation doesn't offer it, you probably have more problems than just a missing typedef.
Yes, given the constraints, it's quite sane.
You might consider checking the value fits instead of simply truncating it upon unpacking it from the
void*
in debug-mode, or even making all further processing of that integer useintptr
instead ofint
to avoid truncation.You could also consider pushing a pointer to an actual
int
instead of theint
itself though that parameter. Be aware that's less efficient though, and opens you to lifetime issues.