I have a value that is stored in a 64 bit integer that I'd like to break down into a bunch of bit fields, ie byteOffset: 6 etc. I've created a struct with a two unions: one for the entire value and one for the broken down values. I was told shifting is not a good method, does anyone know what the best way is?
Shifting. Somebody told you wrong If you want to find 1 bit, you can use bit-masking.
ps : why are you using unions ? They where invented (AFAIK) for memory-use reduction. That's not a problem anymore.
I'm not sure tbh lol, it's the way my manager told me to do it, so that's how I'm doing it. One of the reasons he told me to avoid shifting was if the command changes, ie byteOffset: 6 to byeOffset: 10 than the shift is invalid. I could just be misunderstanding him though.
So if I wanted to get the bits 17:6 of a 64 bit int, would I shift it right 6 spaces, and then store it in something like uint_64 address: 12? ie:
Thanks for your input guys. I figured out why he told me to do that, it's actually a cool trick that's described here: http://www.cplusplus.com/forum/articles/12/. If you use a union in the manner I described, you don't have to do any shifts, the values for each bit field are essentially set automatically.
Be aware, that page is about extracting entire bytes. You need to do a bit more to pull out individual bit values, but it can be done in a similar manner.
Also be aware that bitfields are not portable in the respect that packing order/alignment and so on are not standardized.
Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by
definition, not smart enough to debug it.
- Brian W. Kernighan
It's a long time since I wrote a union. I think I had an overdose of them from a multi-platform source long time ago...
Anyway I think I would have written it like this
Code:
typedef struct
{
union
{
uint64_t all;
struct
{
uint64_t byteOffset : 6;
uint64_t address : 12;
uint64_t bank : 2;
uint64_t : 44;
} parts;
} address;
unsigned int byteCount;
unsigned int src;
unsigned char data;
} addressMap;
to not have to maintain more fields than neccessary. You don't have to have a name for unused fields and in fact in this case you don't have to have it at all. The remaining 44 bits will be present anyway since the underlying type is 64 bits.
As said before bitfields are not fully specified by the standard. In MSVC the byteOffset bits will be the least significant bits in 'all'. In another compiler they might be the most significant bits.
Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by
definition, not smart enough to debug it.
- Brian W. Kernighan
Bookmarks