I'm looking for a portable and elegant way to set the high bit of a pointer type in a situation where we don't know if the pointer will have 32, or 64 bits.
I'm working on some legacy code that we inherited from a defunct company. It used to work in a 32 bit environment and now we need a working 64 bit version too. That means much larger pointers than before, and larger magic numbers to represent invalid values. Currently the best proposal will look broadly like this:
#if ENVIRONMENT_IS_32_BIT
#define INVALID_PTR_CODE 0x80000000
#else
#define INVALID_PTR_CODE 0x8000000000000000
#endif
As I say, I am hoping for something more elegant, and something that will work across different compilers (MSVC, gcc, clang at least). A perfect solution would work for any environment / size of pointer.
static_cast<uintptr_t>(1) << (CHAR_BIT * sizeof(void*) - 1)
would do it.
(Note that the current crop of Intel chips has 48 bit pointers under the hood.)
To get the size of a pointer in bytes you can use sizeof(void *)
, in bits that's sizeof(void *) * CHAR_BIT
. Now you need to get a 1 in that position (keep in mind it's 0 based) so you would do 1ULL << (sizeof(void *) * CHAR_BIT - 1)
. Then just OR that with your number.
Consider the following code:
int *x = (int*)-1; //You set all the bits of `x`
int *y = (int*)((unsigned long long)x >> 1); //y has all bits set besides the msb
x = (int*)(x - y); //subtract y from x to have only th msb set
User contributions licensed under CC BY-SA 3.0