One potential reason to cast an integer to a pointer would be to transport that integer value through an API that accepts a pointer.
For example, many callback-related APIs accept a void *user_data
parameter to be passed as an argument to the callback function. Consider the following function:
void do_async_thing(args..., void (* callback) (int result, void *user_data), void *user_data);
If all you need to pass to the callback is an integer, then instead of passing a pointer to an allocated block of data, you might write:
do_async_thing(
args...,
[](int result, void *request_idx) {
std::cout << "request " << reinterpret_cast<std::uintptr_t>(request_idx) << " returned " << result;
},
reinterpret_cast<void *>(std::uintptr_t{request_idx})
);
Of course you should use std::uintptr_t
, not unsigned long
(e.g. on Windows unsigned long
is 32 bits).
Another reason would be if on your specific platform you happen to know that there is a valid object at that address (e.g. on some embedded device).
Ultimately this is all implementation-defined. std::uintptr_t
may not even exist on a specific platform.