The purpose of intptr_t
and uintptr_t
is that in some applications, you actually do need to do some sort of numeric computation on pointer values, perhaps by flipping individual bits, perhaps by XORing them, etc. In those cases, when you need to work with the numeric value of a pointer, intptr_t
and uintptr_t
are integer types that (if they exist) are guaranteed to be large enough to hold any pointer. This is not true of, say, int
, since int
's size relative to pointer sizes isn't specified.
Because it's fundamentally unsafe to do these conversions, C++ requires that you use reinterpret_cast
to convert to and from intptr_t
and uintptr_t
and pointer types.
If all that you're doing is storing "a pointer to something," and provided that pointer isn't a function pointer or a member function pointer, you can just cast it to void*
. That cast is guaranteed to work and the conversion from void*
back to the original type only requires a static_cast
and is guaranteed to be safe.
The size of intptr_t
and uintptr_t
isn't a good reason to avoid them. They're just for different applications. If you need to do numeric computations on pointers, use those types. Otherwise, if you just need to store "a pointer to something," use a void*
.