Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bit Shifts on a C Pointer?

I'm in the middle of this C project that I wish to make very memory efficient. In several cases, I am using the void *s of a dynamic array structure I wrote in order to hold bits. I wish to use all 64 (in this case) bits.

I soon realized that you cannot actually do any bit manipulation on a pointer. So my solution was the following:

void *p;
((unsigned long)p) << 4;
((unsigned long)p) & 3;

This gets the job done, but only because on my computer, longs and pointers are equal in size. Will this be the case in all (or most) architectures?

And my real question: Is there a more correct way to do bit manipulation on a pointer? I had thought that this approach was somewhat common in C (packing bits into a void *), but I could be mistaken...

like image 213
MADgood Avatar asked Dec 04 '09 06:12

MADgood


2 Answers

If your compiler supports it, C99's <stdint.h> header provides the intptr_t and uintptr_t types that should be large enough to hold a pointer on your system, but are integers, so you can do bit manipulation. It can't really get much more portable than that, if that's what you're looking for.

like image 122
Chris Lutz Avatar answered Nov 03 '22 07:11

Chris Lutz


If you need to do this kind of manipulation on pointers, you can cast them to intptr_t and uintptr_t, both of which can be found in stdint.h. These are guaranteed to be defined as the platform-specific integer type with enough bits to hold a pointer.

There's also ptrdiff_t in there, if you need something to hold the difference between two pointers.

like image 33
Todd Gamblin Avatar answered Nov 03 '22 09:11

Todd Gamblin