smwikipedia
smwikipedia

Reputation: 64433

How does C compiler handle bit-field?

The following bit field sample code is from here. It claims better storage efficiency. But I am wondering how the compiler handles the bit field?

I guess the C compiler HAS TO generate extra instructions for bit-wise manipulation. So although the data size is reduced, the code size is increased.

Any one familiar with the C compiler could shed some light?

#include <stdio.h>

// A space optimized representation of date
struct date
{
   // d has value between 1 and 31, so 5 bits
   // are sufficient
   unsigned int d: 5;

   // m has value between 1 and 12, so 4 bits
   // are sufficient
   unsigned int m: 4;

   unsigned int y;
};

int main()
{
   printf("Size of date is %d bytes\n", sizeof(struct date));
   struct date dt = {31, 12, 2014};
   printf("Date is %d/%d/%d", dt.d, dt.m, dt.y);
   return 0;
} 

Upvotes: 4

Views: 1262

Answers (2)

NPE
NPE

Reputation: 500903

So although the data size is reduced, the code size is increased.

In general, this is correct: it's a trade-off between more compact storage vs faster access.

For example, this is what my compiler produces for the printf statement in your bitfield example:

    movq    _dt@GOTPCREL(%rip), %rax
    movzwl  (%rax), %edx
    movl    %edx, %esi
    andl    $31, %esi     ; -- extract the 5 bits representing day
    shrl    $5, %edx      ; -+ extract the four bits for the month
    andl    $15, %edx     ; /
    movl    4(%rax), %ecx ; -- year doesn't require any bit manipulation
    leaq    L_.str.1(%rip), %rdi
    xorl    %eax, %eax
    callq   _printf

For comparison, the same code when date is a simple struct:

    movq    _dt@GOTPCREL(%rip), %rax
    movl    (%rax), %esi  ; -- day
    movl    4(%rax), %edx ; -- month
    movl    8(%rax), %ecx ; -- year
    leaq    L_.str.1(%rip), %rdi
    xorl    %eax, %eax
    callq   _printf

All of this is of course compiler- and platform-specific.

Upvotes: 6

Israel Unterman
Israel Unterman

Reputation: 13520

As I recall, the doc for bit fields says that this is just a
recommendation for the compiler. The implementation is free
to choose real bits or some less efficient (space-wise) implementation.

Bit field is actually just a convenience syntax for working with bits.

But it turns out that embedded compilers tend to use real bit fields,
since working with bits is a very common task in embedded programming.
And this, of course, must be documented with the compiler, if one wants
to use this feature.

Regarding complexity of the assembler, it makes sense that real bits
require more work from the assembler.

Upvotes: 2

Related Questions