使用位域时以字节为单位的位排序

Posted

技术标签:

【中文标题】使用位域时以字节为单位的位排序【英文标题】:Bit ordering in a byte when using bitfields 【发布时间】:2014-09-09 07:03:49 【问题描述】:

C 参考手册指出“将组件(尤其是位字段)打包到结构中的精确方式取决于实现,但对于每个实现都是可预测的”。

我读到一些编译器在大端机器中从左到右(MSB 到 LSB)打包位字段,而在小端机器中从右到左(LSB 到 MSB)。

以两种不同的方式表示位域是否有理由/优势取决于字节序?

【问题讨论】:

在回答您的问题时,简短的回答是。因为,位是左->右还是右->左打包是硬件约定。没有一种更好/更差的方法,那就是不同的硬件实现如何处理数字/结构来解释/适应机器的字节序。用户只关心他知道位的存储顺序,以便他取回他打算取回的内容。 99.9% 的情况下,用户都不会看到或关心包装/订购。 【参考方案1】:

我还没有实现这一点,但我可以想象它与使用寄存器中的位字段以及在可能的情况下从结构读取/写入整个字有关。如果你以这种方式实现它,而不是进行字节级访问,你当然会“感觉到”字节顺序,因为单词在内存中是字节交换的。

如果你有

 struct color 
  uint32_t red : 8;
  uint32_t green : 8;
  uint32_t blue : 8;
  uint32_t alpha : 8;
 ;

当你这样做时

struct color orange =  .red = 255, .green = 127, .blue = 0, .alpha = 0 ;

它可能被实现(因为字段的大小很方便)

struct color orange;
uint32_t *tmp = *(uint32_t *) &orange;
*tmp = 0xff7f0000;  /* The field values, mapping red to the MSBs. */

现在,由于上面只写了一次uint32_t 大小的内存写入,因此值将在 little-endian 机器上进行字节交换,而不是在 big-endian 机器上进行字节交换,即,当逐字节查看时,表示不一样。

【讨论】:

【参考方案2】:

结构内的位域布局由实现定义。如果您需要可移植的代码,使用它们不是一个好主意。

【讨论】:

以上是关于使用位域时以字节为单位的位排序的主要内容,如果未能解决你的问题,请参考以下文章

定义的变量的位域就是4是啥意思?

求大神指教C语言中的位域

C/C++ 位域知识小结

c语言 关于位域的使用

解压缩位域(movmskb 的逆)

C 和 C++ 中的位域:它们在哪里使用?