tags:

views:

81

answers:

2

If I have a requirement to create a data structure that has the following fields:

16-bit Size field

3-bit Version field

1-bit CRC field

How would I code this struct? I know the Size field would be an unsigned short type, but what about the other two fields?

+1  A: 

First, unsigned short isn't guaranteed to be only 16 bits, just at least 16 bits.

You could do this:

struct Data
{
   unsigned short size : 16;
   unsigned char version : 3;
   unsigned char crc : 1;
};

Assuming you want no padding between the fields, you'll have to issue the appropriate instructions to your compiler. With gcc, you can decorate the structure with __attribute__((packed)):

struct Data
{
   // ...
} __attribute__((packed));

In Visual C++, you can use #pragma pack:

#pragma pack(push, 0)
struct Data
{
   // ...
};
#pragma pack(pop)
Nick Meyer
Even with packing, you're not guaranteed that the bitfields get packed across byte boundaries. I believe VC++ would just pack bytes, so you'd get a 4-byte structure total (2 bytes for size, 1 byte for version and 1 for crc).
jalf
+1  A: 

The following class implements the fields you are looking for as a kind of bitfields.

struct Identifier
{
   unsigned int a; // only bits 0-19 are used
   unsigned int getSize() const {
      return a & 0xFFFF; // access bits 0-15
   }
   unsigned int getVersion() const {
      return (a >> 16) & 7; // access bits 16-18
   }
   unsigned int getCrc() const {
      return (a >> 19) & 1; // access bit 19
   }
   void setSize(unsigned int size) {
      a = a - (a & 0xFFF) + (size & 0xFFF);
   }
   void setVersion(unsigned int version) {
      a = a - (a & (7<<16)) + ((version & 7) << 16);
   }
   void setCrc(unsigned int crc) {
      a = a - (a & (1<<19)) + ((crc & 1) << 19);
   }
};
Danvil