【问题标题】:How does C compiler handle bit-field?C 编译器如何处理位域?
【发布时间】:2016-08-28 13:18:35
【问题描述】:

以下bit field 示例代码来自here。它声称更好的存储效率。但是我想知道编译器是如何处理位域的?

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

【问题讨论】:

  • 你可以查看生成的汇编器来找出答案。
  • @OliverCharlesworth 感谢您的提醒。我怎么会忘记...
  • 这取决于您的平台(底层硬件架构 + 指定编译器),但通常 - 是的,编译器很可能需要添加按位操作(这通常会导致更大的代码段和/或运行时执行速度较慢)。
  • @Nuncameesquecideti:在你最喜欢的搜索引擎上寻找C bitfield...
  • @Nuncameesquecideti:如果我显得粗鲁,我很抱歉,那不是故意的;有人在质疑整个问题的特征参数是否实际上是有效的语法,这让我发笑。

标签: c struct bit-fields


【解决方案1】:

所以虽然数据量减少了,但代码量却增加了。

一般来说,这是正确的:这是更紧凑的存储与更快的访问之间的权衡。

例如,这是我的编译器为您的位域示例中的 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

为了比较,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

所有这些当然是特定于编译器和平台的。

【讨论】:

    【解决方案2】:

    我记得,位字段的文档说这只是一个
    对编译器的建议。实施是免费的
    选择真正的位或一些效率较低(空间方面)的实现。

    位域实际上只是一种使用位的便捷语法。

    但事实证明,嵌入式编译器倾向于使用实位域,
    因为使用位是嵌入式编程中非常常见的任务。
    当然,如果需要,必须使用编译器记录这一点
    使用此功能。

    关于汇编程序的复杂性,真正的位是有意义的
    需要汇编器做更多的工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多