The possible range of virtual addresses is processor and kernel and ABI specific. But I strongly advise against coding some tricks related to some bits in addresses and pointers (since your code might work on some processors, but not on others).
These days, some * x86-64 processors apparently use only 48 bits of the virtual address space, but I don't recommend using that knowledge in your code (it might be wrong within a few years, or on some higher end models). See also x86-64 ABI.
If a pointer is outside that 48 bits range, you get a page fault, i.e. a SIGSEGV, the processor is not ignoring the unimplemented bits. So upper bits of pointers or addresses should be all zeros or all ones.
On Linux, you might play with cat /proc/self/maps
and cat /proc/$$/maps
to get more clues.
BTW, on Linux, you could reserve, using mmap(2) with MAP_ANONYMOUS | MAP_NORESERVE
, some large address range (and either later call mmap
with MAP_FIXED
inside it, or never use it) to avoid it being later used by your process (or, as commented by damon, use MAP_32BITS
which is x86-64 specific) This is probably more sensible than relying on the address bits to be restricted to 48 bits.
Also, catching SIGSEGV
on Linux is tricky (you'll need some processor specific code) and costly. Perhaps you want some external pager mechanism (which exists on GNU Hurd, but not on Linux). Or mmap
-ing some pseudo-file on some FUSE filesystem.
NB: most x86-64 processors have only 48 bits of addresses, but I don't recommend using that.
Note 2: Processor makers remembered what IBM/360 did: ignoring the upper address bits (originally 24 bits). When IBM had to extend address to 31 bits it was a nightmare for the software industry. So hardware makers understood the lesson, and disallow today (in hardware) playing naughty tricks on unused address bits.