I have a 64bit integer that is used as a handle. The 64bits must be sliced into the following fields, to be accessed individually:
size : 30 bits
offset : 30 bits
invalid flag : 1 bit
immutable flag : 1 bit
type flag : 1 bit
mapped flag : 1 bit
The two ways I can think of to achieve this are:
1) Traditional bit operations (& | << >>
), etc. But I find this a bit cryptic.
2) Use a bitfield struct:
#pragma pack(push, 1)
struct Handle {
uint32_t size : 30;
uint32_t offset : 30;
uint8_t invalid : 1;
uint8_t immutable : 1;
uint8_t type : 1;
uint8_t mapped : 1;
};
#pragma pack(pop)
Then accessing a field becomes very clear:
handle.invalid = 1;
But I understand bitfields are quite problematic and non-portable.
I'm looking for ways to implement this bit manipulation with the object of maximizing code clarity and readability. Which approach should I take?
Side notes:
The handle size must not exceed 64bits;
The order these fields are laid in memory is irrelevant, as long as each field size is respected;
The handles are not saved/loaded to file, so I don't have to worry about endianess.