15

我正在使用 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;

字段的哪一端是最高有效位?

4

3 回答 3

25

C99 标准 6.7.2.1/10(强调我的):

实现可以分配任何大到足以容纳位域的可寻址存储单元。如果有足够的空间剩余,紧跟在结构中另一个位域之后的位域将被打包到同一单元的相邻位中。如果剩余空间不足,则将不适合的位域放入下一个单元还是与相邻单元重叠是实现定义的。单元内位域的分配顺序(高位到低位或低位到高位)是实现定义的。未指定可寻址存储单元的对齐方式。

因此,您的编译器实现必须记录该顺序。

然而,关于如何实现位域的很多内容是实现定义或未指定的,因此使用它们以可移植的方式对硬件、线路协议或文件格式位域进行建模并不值得尝试。

如果您希望您的“位字段”对程序外部的某些内容(如上述内容)进行建模,请使用显式掩码,使用标准位运算符(|、'& ,~ ,<<` 等)设置和清除位. 使用 helper 内联函数(如果必须的话,甚至可以使用宏)来使代码更容易/更清晰。

于 2010-12-28T17:20:34.137 回答
8

Visual Studio 2008 编译器文档指出:

声明为位域的数据的顺序是从低位到高位

来自“C++ 位域”,MSDN C++ 语言参考,Visual Studio 2008 版

于 2016-12-15T05:05:06.113 回答
2

如果您要询问 myBitField 中的哪些位存储在内存中字节的哪些位中,那是 C 标准明确未定义的。你必须通过实验来学习。如果您正在做一些真正重要的事情,那么可能值得使用一种方法,将 #definefield1作为十六进制值(例如,0x400x02)并将其放在您想要的位置。

于 2010-12-28T16:31:54.683 回答