smwikipedia smwikipedia - 3 months ago 16
C Question

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;
}

NPE NPE
Answer

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.