如何获取位域以正确的顺序排列我的位?
首先,相关应用程序始终位于同一处理器上,并且编译器始终为 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__));
(实际上,这是 C++,所以我说的是 g++。)
现在假设我希望 a 是一个六位整数。
现在,我明白为什么这不起作用,但我编写了以下结构:
struct Bits2 {
unsigned int a:6;
unsigned int b:1;
unsigned int c:1;
unsigned int d:1;
} __attribute__((__packed__));
将 b、c 和 d 设置为 1,和 a 到 0 会产生以下两个字节:
c0 01
这不是我想要的。我希望看到这一点:
e0 00
有没有办法指定一个结构,该结构在第一个字节的最高有效位中具有三位,并且在第一个字节的五个最低有效位和第二个字节的最高有效位中包含六个位?
请注意,我无法控制这些位的布局位置:它是由其他人的接口定义的位布局。
To begin with, the application in question is always going to be on the same processor, and the compiler is always gcc, so I'm not concerned about bitfields not being portable.
gcc lays out bitfields such that the first listed field corresponds to least significant bit of a byte. So the following structure, with a=0, b=1, c=1, d=1, you get a byte of value e0.
struct Bits {
unsigned int a:5;
unsigned int b:1;
unsigned int c:1;
unsigned int d:1;
} __attribute__((__packed__));
(Actually, this is C++, so I'm talking about g++.)
Now let's say I'd like a to be a six bit integer.
Now, I can see why this won't work, but I coded the following structure:
struct Bits2 {
unsigned int a:6;
unsigned int b:1;
unsigned int c:1;
unsigned int d:1;
} __attribute__((__packed__));
Setting b, c, and d to 1, and a to 0 results in the following two bytes:
c0 01
This isn't what I wanted. I was hoping to see this:
e0 00
Is there any way to specify a structure that has three bits in the most significant bits of the first byte and six bits spanning the five least significant bits of the first byte and the most significant bit of the second?
Please be aware that I have no control over where these bits are supposed to be laid out: it's a layout of bits that are defined by someone else's interface.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
(请注意,所有这些都是特定于 gcc 的注释 - 我很清楚位域的布局是实现定义的)。
不在小端机器上:问题在于,在小端机器上,第二个字节的最高有效位不被视为与第一个字节的最低有效位“相邻”。
不过,您可以将位域与
ntohs()
函数结合起来:但是,我强烈建议您避免使用位域,而使用移位和掩码。
(Note that all of this is gcc-specific commentary - I'm well aware that the layout of bitfields is implementation-defined).
Not on a little-endian machine: The problem is that on a little-endian machine, the most significant bit of the second byte isn't considered "adjacent" to the least significant bits of the first byte.
You can, however, combine the bitfields with the
ntohs()
function:However, I strongly recommend you avoid bitfields and instead use shifting and masks.
通常,您无法对联合的打包方式做出强有力的假设,每个编译器实现都可能选择以不同的方式打包它(以节省空间或对齐字节内的位字段)。
我建议您只使用掩码和按位运算符。
来自 此链接:
Usually you can't do strong assumptions on how the union will be packed, every compiler implementation may choose to pack it differently (to save space or align bitfields inside bytes).
I would suggest you to just work out with masking and bitwise operators..
from this link:
C/C++ 无法指定结构体的逐位内存布局,因此您需要对 8 或 16 位(无符号)整数(来自
的 uint8_t、uint16_t 进行手动位移和屏蔽)
或
)。在我所知道的十几种编程语言中,只有极少数允许您为位字段指定逐位内存布局:Ada、Erlang、VHDL(和 Verilog)。
(如果您想向该列表添加更多语言,请访问社区 wiki。)
C/C++ has no means of specifying the bit by bit memory layout of structs, so you will need to do manual bit shifting and masking on 8 or 16bit (unsigned) integers (uint8_t, uint16_t from
<stdint.h>
or<cstdint>
).Of the good dozen of programming languages I know, only very few allow you to specify bit-by-bit memory layout for bit fields: Ada, Erlang, VHDL (and Verilog).
(Community wiki if you want to add more languages to that list.)