There is no portable way to do this.
The standard guarantees that you can convert a void*
to uintptr_t
without loss of information -- but it doesn't guarantee that uintptr_t
exists. A conforming implementation might not have an integer type wide enough to hold a converted pointer without loss of information.
And even if uintptr_t
exists, the language only guarantees that you can convert void*
to uintptr_t
without loss of information. A conforming permission might have, for example, 64-bit object pointers, 64-bit uintprt_t
, and 128-bit function pointers.
It's likely, in most implementations, that you can convert a function pointer to uintptr_t
without loss of information. (I think POSIX guarantees this, though the ISO C and C++ standards do not.)
Once you've done that, probably using a reinterpret_cast
, you have an unsigned integer, which you can shift as you like.
The result of this shift will almost certainly be meaningless garbage. C++ doesn't prevent you from shooting yourself in the foot, which is what you appear to be trying to do.