Utkarsh Patel
Utkarsh Patel

Reputation: 99

Bitfield concept in structure

#include<stdio.h>

int main()
{
        struct value
        {
                int bit1:1;
                int bit2:4;
                int bit3:4;
        }bit;

        printf("%d\n",sizeof(bit));
}

I am using GCC, it is showing me the sizeof(bit) value as 4. Can you please explain how it works internally?

Upvotes: 2

Views: 86

Answers (2)

Sourav Ghosh
Sourav Ghosh

Reputation: 134326

To quote C11 standard, chapter §6.7.2.1, Structure and union specifiers, (emphasis mine)

implementation may allocate any addressable storage unit large enough to hold a bitfield. 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. 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.....

In your case, as the (first variable type) int size is enough to pack all the bit-fielded variables into one int, it's doing so.

Thus, essentially your sizeof(bit) becomes equivalent to sizeof(int) which is likely to produce the value 4, in 32 bit systems.

That said, sizeof produces a value of type size_t. You should use %zu format specifier to print that value.


[Added by Community Edit]

  • Case 1:

    If you use char as shown below, it'll show size as 1, because 7 bits can fit in a char.

    #include<stdio.h>
    
    int main(void)
    {
        struct value
        {
                char bit1:1;
                char bit2:2;
                char bit3:4;
        }bit;
    
        printf("%d\n",sizeof(bit));
    }
    
  • Case 2:

    In below case, the result will be '2' because it needs 2 chars to store 9 bits in total.

        char bit1:1;
        char bit2:4;
        char bit3:4;
    

Upvotes: 1

unwind
unwind

Reputation: 399823

The compiler decided to lay out the bitfields in a single int, which is 32 bits on your platform. That means the structure as a whole requires 32 bits, even though the usable part of the structure is smaller.

Most machines aren't bit-addressable, so it really can't create an object that is 9 bits wide. It could have chosen 16 bits, and you can probably persuade it to do so with some #pragma or attribute magic. 32 bits is probably the most native size which gives best performance.

Upvotes: 1

Related Questions