Reputation: 64433
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
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
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