The result of casting a pointer to an integer using
reinterpret_cast is implementation-defined, but "... is intended to be unsurprising to those who know the addressing structure of the underlying machine."
int x = 42; int* p = &x; long addr = reinterpret_cast<long>(p); std::cout << addr << "\n"; // prints some numeric address, // probably in the architecture's native address format
Likewise, the pointer obtained by conversion from an integer is also implementation-defined.
The right way to store a pointer as an integer is using the
// `uintptr_t` was not in C++03. It's in C99, in <stdint.h>, as an optional type #include <stdint.h> uintptr_t uip;
// There is an optional `std::uintptr_t` in C++11 #include <cstdint> std::uintptr_t uip;
C++11 refers to C99 for the definition
uintptr_t (C99 standard, 18.104.22.168):
an unsigned integer type with the property that any valid pointer to
voidcan be converted to this type, then converted back to pointer to
void, and the result will compare equal to the original pointer.
While, for the majority of modern platforms, you can assume a flat address space and that arithmetic on
uintptr_t is equivalent to arithmetic on
char *, it's entirely possible for an implementation to perform any transformation when casting
void * to
uintptr_t as long the transformation can be reversed when casting back from
On XSI-conformant (X/Open System Interfaces) systems,
uintptr_t types are required, otherwise they are optional.
Within the meaning of the C standard, functions aren't objects; it isn't guaranteed by the C standard that
uintptr_t can hold a function pointer. Anyway POSIX (2.12.3) conformance requires that:
All function pointer types shall have the same representation as the type pointer to void. Conversion of a function pointer to void * shall not alter the representation. A void * value resulting from such a conversion can be converted back to the original function pointer type, using an explicit cast, without loss of information.
When typedef names differing only in the absence or presence of the initial u are defined, they shall denote corresponding signed and unsigned types as described in 6.2.5; an implementation providing one of these corresponding types shall also provide the other.
uintptr_t might make sense if you want to do things to the bits of the pointer that you can't do as sensibly with a signed integer.