我正在使用Visual Studio 2008为Windows XP / Vista / 7编写C ++应用程序。我的一些结构使用位字段,如示例所示。
typedef struct myStruct_tag
{
BYTE myVar1;
WORD myVar2;
WORD myVar3;
union
{
struct
{
BYTE :1;
BYTE field1 :1;
BYTE field2 :1;
BYTE reserved :5;
} myBitField;
BYTE myVar4;
};
BYTE myVar5;
BYTE myVar6;
} myStruct_t;
该字段的哪一端是最重要的位?
答案 0 :(得分:21)
C99标准6.7.2.1/10(强调我的):
实现可以分配足够大的任何可寻址存储单元来保存位域。如果剩余足够的空间,则紧跟在结构中的另一个位字段之后的位字段将被打包到相同单元的相邻位中。如果剩余的空间不足,则是否将不适合的位域放入下一个单元或重叠相邻单元是实现定义的。 单元内位域(高位到低位或低位到高位)的分配顺序是实现定义的。未指定可寻址存储单元的对齐。
因此,订单必须由编译器实现记录。
然而,如何实现位域是实现定义的还是未指定的,使用它们以便携方式建模硬件,线协议或文件格式位字段并不值得尝试。
如果您希望“位字段”为程序外部的某些内容建模(如上所述),请使用显式掩码,使用标准的逐位运算符(|
,'&}设置和清除这些位; ,
〜,
<<`等等。使用帮助器内联函数(如果必须,甚至使用宏)可以使代码更容易/更清晰。
答案 1 :(得分:6)
Visual Studio 2008编译器文档指示:
声明为位字段的数据顺序是从低位到高位
来自"C++ Bit Fields", MSDN C++ Language Reference, Visual Studio 2008 version
答案 2 :(得分:2)
如果你问的是myBitField中哪些位存储在内存中字节的哪些位上,那么C标准明确地未定义这些位。你必须通过实验来学习。这可能是值得的,如果你正在做一些真正重要的事情,而是使用一种方法,你将#field1
作为十六进制值(例如,0x40
或0x02
)和把它放在你想要的地方。