8.5.2 Bit Fields in Structures

MPLAB XC32 C/C++ Compiler fully supports bit fields in structures.

Bit fields are always allocated within 8-bit storage units, even though it is usual to use the type unsigned int in the definition. Storage units are aligned on a 32-bit boundary, although this can be changed using the packed attribute.

The first bit defined will be the Least Significant bit of the word in which it will be stored. When a bit field is declared, it is allocated within the current 8-bit unit if it will fit; otherwise, a new byte is allocated within the structure. Bit fields can never cross the boundary between 8-bit allocation units. For example, the declaration:

struct {
           unsigned      lo : 1;
           unsigned      dummy : 6;
           unsigned      hi : 1;
} foo;

will produce a structure occupying 1 byte.

Unnamed bit fields may be declared to pad out unused space between active bits in control registers. For example, if dummy is never referenced, the structure above could have been declared as:

struct {
           unsigned      lo : 1;
           unsigned         : 6;
           unsigned      hi : 1;
} foo;

A structure with bit fields may be initialized by supplying a comma-separated list of initial values for each field. For example:

struct {
           unsigned      lo : 1;
           unsigned      mid: 6;
           unsigned      hi : 1;
} foo = {1, 8, 0};

Structures with unnamed bit fields may be initialized. No initial value should be supplied for the unnamed members, for example:

struct {
           unsigned      lo : 1;
           unsigned         : 6;
           unsigned      hi : 1;
} foo = {1, 0};

will initialize the members lo and hi correctly.

The MPLAB XC compiler supports anonymous unions. These are unions with no identifier and whose members can be accessed without referencing the enclosing union. These unions can be used when placing inside structures. For example:

struct {
        union {
        int x;
        double y;
   };
} aaa;

int main(void)
{
    aaa.x = 99;
    // ...}

Here, the union is not named and its members accessed as if they are part of the structure. Anonymous unions are not part of any C Standard and so their use limits the portability of any code.