Fork me on GitHub

Project Notes

#148 Fields

Using bitfields in C

Notes

Bit fields are data structures for accessing and manipulating the individual bits of a data value. Bit fields are supported in C and C++, however some details are implementation dependent, such as internal allocation details and how out of range values are handled.

A bit field declaration is a struct with one or more fields defined:

struct {
   type [member_name] : width ;
   type [member_name] : width ;
   etc
};
  • type - integer type that determines how a field’s value is interpreted
  • member_name - optional name of the element
  • width - number of bits in the field

A width of zero is only allowed for nameless bitfields and specifies that the next bit field in the class definition will begin at an allocation unit’s boundary.

Declaring Bit Fields

As an anonymous struct variable:

struct {
    uint8_t a      : 1;
    uint8_t b      : 1;
} bitfield;
bitfield.a = 1;

As a name struct type:

struct MyBitfieldType {
    uint8_t a      : 1;
    uint8_t b      : 1;
};

struct MyBitfieldType bitfield;
bitfield.a = 1;

Using pointers to a bitfield:

struct MyBitfieldType * bitfield_pointer;
bitfield_pointer = &bitfield;
assert(bitfield.a == bitfield_pointer->a);

Using a Union

A union can facilitate the simultaneus bitwise and memory-level access. HOWEVER, the internal layout of a bitfield is implementation (compiler and platform) dependent, so this approach while convenient would need verification for each target environment.

  union {
    struct {
      uint8_t a      : 1;
      uint8_t b      : 1;
    } bits;

    uint16_t memory;
  } bitset;

bitset.bits.a = 0;
bitset.memory = 0xFFFF;
assert(bitset.bits.a == 1);

Running the Examples

See example.c for details. A makefile compiles and runs:

$ make
gcc -Wall -O0    example.c   -o example
./example

===== test_anonymous_narrow
Memory size occupied by bitfield : 8 bits
Memory contents (initial): 0b00000000
Memory contents (set)    : 0b00000011
Memory contents (cleared): 0b00000000

===== test_anonymous_aligned_wide
Memory size occupied by bitfield : 16 bits
Memory contents (initial): 0b0000000000000000
Memory contents (set)    : 0b0000001100001101
Memory contents (cleared): 0b0000000000000000

===== test_named_bitfield
Memory size occupied by bitfield : 8 bits
Memory contents (initial): 0b00000000
Memory contents (set)    : 0b00000011
Memory contents (cleared): 0b00000000

===== test_union
bitset.memory_value (initial)    : 0b0000000000000000
bitset.memory_value (set)        : 0b0000000000000011
bitset.bits.a                    : 0b1
bitset.bits.b                    : 0b1
bitset.memory_value (clear b)    : 0b0000000000000001
bitset.bits.a                    : 0b1
bitset.bits.b                    : 0b0
bitset.memory_value (direct set) : 0b1010101010101111
bitset.bits.a                    : 0b1
bitset.bits.b                    : 0b1

===== test_with_pointers
bitset.a                    : 0b0
bitset.b                    : 0b1
bitset_pointer->a           : 0b0
bitset_pointer->b           : 0b1

Credits and References

About LCK#148 c
Project Source on GitHub Return to the Project Catalog

LittleCodingKata is my collection of programming exercises, research and code toys broadly spanning things that relate to programming and software development (languages, frameworks and tools).

These range from the trivial to the complex and serious. Many are inspired by existing work and I'll note credits and references where applicable. The focus is quite scattered, as I variously work on things new and important in the moment, or go back to revisit things from the past.

This is primarily a personal collection for my own edification and learning, but anyone who stumbles by is welcome to borrow, steal or reference the work here. And if you spot errors or issues I'd really appreciate some feedback - create an issue, send me an email or even send a pull-request.

LittleArduinoProjects LittleModelArt More on my blog