pack bits in a struct c++ / arduino

  • A+
Category:Languages

I have a struct:

typedef struct {   uint8_t month;  // 1..12 [4 bits]   uint8_t date;   // 1..31 [5 bits]   uint8_t hour;   // 00..23 [5 bits]   uint8_t minute; // 00..59 [6 bits]   uint8_t second; // 00..59 [6 bits] } TimeStamp; 

but I would like to pack it so it only consumes 4 bytes instead of 5.

Is there a way of shifting the bits to create a tighter struct?

It might not seem much but it is going into EEPROM, so 1 byte saved is an extra 512 bytes in a 4Kb page (and I can use those extra 6 bits left over for something else too).


What you're looking for are bitfields.

They look like this:

typedef struct {   uint32_t month  : 4;   // 1..12 [4 bits]   uint32_t date   : 5;   // 1..31 [5 bits]   uint32_t hour   : 5;   // 00..23 [5 bits]   uint32_t minute : 6;   // 00..59 [6 bits]   uint32_t second : 6;   // 00..59 [6 bits] } TimeStamp; 

Depending on your compiler, in order to fit into 4 bytes with no padding, the size of the members must be 4 bytes (i.e. uint32_t) in this case. Otherwise the struct members will get padded to not overflow on each byte boundary, resulting in a struct of 5 bytes, if using uint8_t. Using this as a general rule should help prevent compiler discrepancies.

Here's an MSDN link that goes a bit in depth into bitfields:

C++ Bit Fields

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: