0

我用匿名结构和 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

盖伊

4

3 回答 3

3

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

于 2013-08-30T10:10:00.913 回答
3

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

struct dns_flags {
    uint16_t flagsValue; 
    uint16_t qr() const { return flagsValue & 1; }
    ...
};
于 2013-08-30T09:20:52.563 回答
2

我不知道标准要求是什么,您可以参考 Mats Peterson 的回答,但这就是该结构的内存布局方式。

这是因为你的机器是小端的,并且值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位在0x81801转换为int类型)。

并且写入的值0x8280RA具有价值0并且zero将具有1

于 2013-08-30T10:12:53.067 回答