I had thought you need the pointer-sized integer types and mustn't do this directly to an actual pointer, but maybe I was wrong (in theory, obviously practice doesn't follow but that's a dangerous game)
In modern C++, the technically "correct" and safe way to spell this trick is exactly as you suggested: using uintptr_t (or intptr_t).
https://blog.rust-lang.org/2025/01/09/Rust-1.84.0/#strict-pr...
https://doc.rust-lang.org/std/primitive.pointer.html#method....
Rust's MIRI is able to run code which uses this (a strict provenance API) because although MIRI's pointers are some mysterious internal type, it can track that we mapped them to hide our tags, and then later mapped back from the tagged point to recover our "real" pointer and see that's fine.
This isn't an unsafe operation. Dereferencing a pointer is unsafe, but twiddling the bits is fine, it just means whoever writes the unsafe dereferencing part of your codebase needs to be very careful about these pointers e.g. making sure the ones you've smuggled a tag in aren't dereferenced 'cos that's Undefined Behaviour.
It's clear to me how this works in Rust, it's just unclear still in C++
thecloudlet•3h ago
https://news.ycombinator.com/item?id=47259961