Understanding bit field in c

bit field in c

In C language structure and union support a very important feature that is the bit field. The bit field allows the packing of data in a structure or union and prevents the wastage of memory.

Note: The layout of the bit-fields is implementation-defined that is the reason a lot of people are avoiding the use of bit-filed.

Syntax:

In C language declaration of the bit-field structure or union is similar to the declaration of the normal structure or union, the main difference is that bit-field member is declared with a specified number of bits preceded by the colon.

struct
{
 type-specifier declarator opt : constant-expression
};

In the above declaration, constant-expression specifies the width of the field in bits and must be a non-negative integer value. If the value is zero, the declaration has no declarator.

The type-specifier for the declarator must be _Bool, signed int, unsigned int, or some other implementation-defined type.It is implementation-defined whether atomic types are permitted.

Example,

Let’s take an example to understand the structure bit field.
struct packed_data {
unsigned int data1:1;
unsigned int data2:1;
unsigned int data3:1;
unsigned int data4:1;
unsigned int data5:1;
unsigned int data6:3;
unsigned int data7:6;
} sPackData;

In below statement, structure packed_data contains 7 members. In which five-member (data1 to data5) has 1 bit and 6th and 7th member has the 3 and 6 bits.

Way to access the member:

sPackData.data6 = 3;

For learning more, you can signup for the free trial of this popular c video course by Kenny Kerr.

 Use of bit field in embedded C?

Suppose a microcontroller has a port of 8 pins and each pin are connected to the led. In that scenario using the bitfield, we can easily change the status of the led.

So first we need to create a bit-field structure to mapping with the micro-controller port.

Create a pointer to the above describe bit-field and assign the address of the PORT to the pointer which you want to access.

volatile LED_BAR_STATE *pLedState = (volatile LED_BAR_STATE *)0xE002C000;

Now you can access the individual led using the pointer.

pLedState->LED1 = 1;

pLedState->LED2 = 0;

Note: Here, I am only describing, how is the bit-field work. I am not suggesting to use bit-field in the mapping of a hardware register because the allocation of bit-field depends upon the compiler.

Might be the result of one compiler can be different from another compiler. So we should avoid the compiler-dependent code, In simple word, avoid using bit fields for the mapping of the hardware register.

Some important points about bit field in c

  • If we are compiled the same C program that uses the bit-field on a different system, the result of the program may vary (C program may not work properly).
  • The order of allocation of bit-fields within a unit low-order to high-order or high-order to low-order ( depend on endianness )is implementation-defined.

When running on a machine (Linux):

00000000000000000000000000000000
00000000000000000000000000010001
00000000000000000010001000010001
00000000001100110010001000010001
01000100001100110010001000010001

  • If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined.

Output:

Implementation-Dependent

  • We can not create a pointer to the bit-field and also not use the address-of operator (&) to the bit-field member.

Output:

[Error] cannot take address of bit-field ‘a’

  • We can not create an array of a bit field in c.

Output:

[Error] bit-field ‘b’ has an invalid type.

  • The bit fields must also be long enough to contain the bit pattern. See the below example,

  • The alignment of the addressable storage unit is unspecified.
  • If enough space remains, a bit field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit.
  • A bit field declaration with no declarator is called unnamed bit field. If the width of the unnamed bit-field is 0 (zero), it indicates that no further bit-field is to be packed into the unit in which the previous bitfield, if any, was placed.

See the below example, here I have created two structure. In the second structure, I am using the unnamed bit-field with 0 widths for the force unalignment.

Output:

Size of sData1 = 4
Size of sData2 = 8

  • We can not calculate the size of the bit field in c using the sizeof operator.

Output:

[Error] ‘sizeof’ applied to a bit field.



Leave a Reply