如何获取位域以正确的顺序排列我的位?

Jim*_*ker 5 c c++ gcc bit-fields

首先,相关应用程序始终位于同一处理器上,并且编译器始终为 gcc,因此我不担心位域不可移植。

gcc 布局位字段,使得第一个列出的字段对应于字节的最低有效位。因此,在以下结构中,a = 0,b = 1,c = 1,d = 1,您将得到一个字节值 e0。

struct Bits {
  unsigned int a:5;
  unsigned int b:1;
  unsigned int c:1;
  unsigned int d:1;
} __attribute__((__packed__));
Run Code Online (Sandbox Code Playgroud)

(实际上,这是C++,所以我说的是g++。)

现在假设我希望a是一个六位整数。

现在,我明白为什么这不起作用,但我编写了以下结构:

struct Bits2 {
  unsigned int a:6;
  unsigned int b:1;
  unsigned int c:1;
  unsigned int d:1;
} __attribute__((__packed__));
Run Code Online (Sandbox Code Playgroud)

将bcd设置为 1,将a设置为 0 会产生以下两个字节:

c0 01
Run Code Online (Sandbox Code Playgroud)

这不是我想要的。我希望看到这个:

e0 00
Run Code Online (Sandbox Code Playgroud)

有没有办法指定一个结构,该结构在第一个字节的最高有效位中具有三位,并且在第一个字节的五个最低有效位和第二个字节的最高有效位中具有六个位?

请注意,我无法控制这些位的布局位置:它是由其他人的接口定义的位布局。

caf*_*caf 3

(请注意,所有这些都是特定于 gcc 的注释 - 我很清楚位域的布局是实现定义的)。

不在小端机器上:问题在于,在小端机器上,第二个字节的最高有效位不被视为与第一个字节的最低有效位“相邻”。

但是,您可以将位域与函数结合起来ntohs()

union u_Bits2{
    struct Bits2 {
      uint16_t _padding:7;
      uint16_t a:6;
      uint16_t b:1;
      uint16_t c:1;
      uint16_t d:1;
    } bits __attribute__((__packed__));
    uint16_t word;
}

union u_Bits2 flags;
flags.word = ntohs(flag_bytes_from_network);
Run Code Online (Sandbox Code Playgroud)

但是,我强烈建议您避免使用位域,而使用移位和掩码。