An object pointer (including void*
) or function pointer can be converted to an integer type using reinterpret_cast
. This will only compile if the destination type is long enough. The result is implementation-defined and typically yields the numeric address of the byte in memory that the pointer pointers to.
Typically, long
or unsigned long
is long enough to hold any pointer value, but this is not guaranteed by the standard.
If the types std::intptr_t
and std::uintptr_t
exist, they are guaranteed to be long enough to hold a void*
(and hence any pointer to object type). However, they are not guaranteed to be long enough to hold a function pointer.
Similarly, reinterpret_cast
can be used to convert an integer type into a pointer type. Again the result is implementation-defined, but a pointer value is guaranteed to be unchanged by a round trip through an integer type. The standard does not guarantee that the value zero is converted to a null pointer.
void register_callback(void (*fp)(void*), void* arg); // probably a C API
void my_callback(void* x) {
std::cout << "the value is: " << reinterpret_cast<long>(x); // will probably compile
}
long x;
std::cin >> x;
register_callback(my_callback,
reinterpret_cast<void*>(x)); // hopefully this doesn't lose information...