CrossWorks offers extended bitfield types, an extension to the ISO standard to pack bitfields into smaller storage units. According to the ISO standard, bitfields can only be packed into int and unsigned storage units. As an extension, CrossWorks accepts bitfields declared with the following types:

When declaring a bitfield in these types, the compiler will pack data into a storage unit appropriate for that type.

For instance, consider the standard structure:

struct {
  unsigned x : 1;
  unsigned y : 1;
}

In this instance, x and y are packed into an integer storage unit, which is the native word size of the processor. In doing so, the size and alignment of the structure is derived from the declared type of the fields, unsigned.

If the structure were declared using char instead of int, the fields would be packed into the smallest addressable unit instead, and the size and alignment requirements of the structure would change accordingly:

struct {
  unsigned char x : 1;
  unsigned char y : 1;
}

You can mix types within a structure. When the compiler detects that the packing unit changes, it restarts packing into the appropriate storage unit declared by the type:

struct {
  // Pack into first byte, bits 0 through 6, bit 7 unused
  unsigned char  c0 : 1;
  unsigned char  c1 : 1;
  unsigned char  c2 : 5;

  // Align to the following 16-bit unit and start packing
  unsigned short s0 : 4;
  unsigned short s1 : 5;
  unsigned short s2 : 7;
}

To eliminate the padding byte between the char and short fields, you can use the CrossWorks Packed structures extension.

You can use this extension in a union to directly address bits in a byte:

typedef __packed union {
  unsigned char byte;
  __packed struct {
    unsigned char b0 : 1;
    unsigned char b1 : 1;
    unsigned char b2 : 1;
    unsigned char b3 : 1;
    unsigned char b4 : 1;
    unsigned char b5 : 1;
    unsigned char b6 : 1;
    unsigned char b7 : 1;
  } bits;
} byte_union_t;