smw*_*dia 3 c struct bit-fields
以下bit field示例代码来自此处.它声称存储效率更高.但我想知道编译器如何处理位字段?
我猜的C编译器必须生成逐位操作额外的指令.因此,尽管数据大小减小,但代码大小也会增加.
任何熟悉C编译器的人都可以解释一下吗?
#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;
}
Run Code Online (Sandbox Code Playgroud)
因此,尽管数据大小减小,但代码大小也会增加.
一般来说,这是正确的:它是更紧凑的存储与更快的访问之间的权衡.
例如,这是我的编译器为printf你的位域示例中的语句生成的:
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
Run Code Online (Sandbox Code Playgroud)
为了比较,相同的代码何时date是简单的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
Run Code Online (Sandbox Code Playgroud)
所有这些当然都是编译器和平台特定的.