结构与位字段重新排序?

时间:2013-08-30 09:10:15

标签: c++ c struct

我用匿名结构和uninon写了一个结构:

字节为typedef unsigned char byte

struct dns_flags
{
    union 
    {
        struct 
        {
            byte QR : 1;
            byte opCode : 4; 
            byte AA : 1;
            byte TC : 1;
            byte RD : 1;
            byte RA : 1;
            byte zero : 3; 
            byte rcode : 4; 
        };

        uint16_t flagsValue; 
    };

};

代表DNS协议标志。

我在#pragma pack(push,1)时使用了sizeof(dns_flags) == 2flagsValue == 0x8180;然后rcode = 8。所以我想知道结构在内存中的布局:rcode半字节是更高的一个?!这没有任何意义......使用VS2012

3 个答案:

答案 0 :(得分:3)

不要在联合中使用位字段来寻址无符号整数的位(该实现具有编译器和机器依赖性)。兼容的解决方案:

struct dns_flags {
    uint16_t flagsValue; 
    uint16_t qr() const { return flagsValue & 1; }
    ...
};

答案 1 :(得分:3)

标准中未指定位域的实际顺序。完全取决于编译器做它喜欢的事情(只要它每次都以相同的方式完成)。我认为大多数编译器都遵循机器本身的字节顺序(因此第一个字段是小端机器中的最低位,并且是大端机器中的最高位),但这不是保证,只是“约定”。

答案 2 :(得分:2)

我不知道标准的要求是什么,你可以参考Mats Peterson的答案,但这就是这个结构的内存布局。

这是因为您的计算机是小Endian,值0x8180存储为8081,即较低字节0x80位于较低地址,较高字节0x81位于较高位置地址。

(LB)(0x80)字节(7-> 0)= 0x80

(HB)(0x81)字节(15-> 8)= 0x81

  This forms your lower byte (0x80)
byte QR : 1;        <------- Lower Address    --> ( bit 0)  
byte opCode : 4;                              --> ( bits 1,2,3,4)
byte AA : 1;                                  --> ( bit 5)
byte TC : 1;                                  --> ( bit 6)
byte RD : 1;                                  --> ( bit 7)

And this is the higher byte (0x81)
byte RA : 1;                                  --# (bit 8)
byte zero : 3;                                --# (bits 9,10,11)
byte rcode : 4;     <------- Higher Address   --# (bits 12,13,14,15)

如果您检查RA的值,它应该是1,因为它位于8位且8th中的0x8180位为1(已转换)到int类型)。

所写的值为0x8280,然后RA的值为0zero的值为1