C++ 将115位数据强制转换为位字段的并集会得到错误的结果

C++ 将115位数据强制转换为位字段的并集会得到错误的结果,c++,endianness,unions,bit-fields,C++,Endianness,Unions,Bit Fields,我试图将一个115位的数据转换为一个位域的并集,结果是错误的 安装程序 我有两种类型的数据: Configuration: data[62:0] addr[113:107] type[114] RawBits: lowBits[63:0] highBits[115:64] 因此,我定义了以下位字段和并集: typedef struct RawBits { unsigned long in

我试图将一个115位的数据转换为一个位域的并集,结果是错误的

安装程序 我有两种类型的数据:

Configuration: data[62:0]
               addr[113:107]
               type[114]

RawBits:       lowBits[63:0]
               highBits[115:64]
因此,我定义了以下位字段和并集:

typedef struct RawBits {
  unsigned long int lowBits:64;
  unsigned long int highBits:51;
  unsigned long int reserved :13;
} __attribute__((packed))rawBits;

typedef struct Configuration {
  unsigned long int data : 62;
  unsigned long int addr : 7;
  unsigned long int type : 1;
  unsigned long int reserved : 58;
} __attribute__((packed))Configuration ;

typedef union Instruction {
  RawBits bits;
  Configuration configuration;
} __attribute__((packed))Instruction;
作为我使用的数据:

uint8_t configuration_test[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00,
为了将缓冲区转换为union类型,我使用了简单的转换:

Instruction *instruction = (Instruction *)configuration_test;
预期结果 实际结果
编译器可以自由地以其选择的任何方式表示位字段。选择将该数组作为
指令键入pun的那一刻,就是程序行为未定义的那一刻。。。或者至少是特定于实现的。您使用哪种编译器和版本?@paddy我需要位字段来表示硬件寄存器,因此它需要紧密打包。位字段不能“跨越”整数–
配置
比您想象的要大。使用位掩码和移位。相关:
instruction->bits->lowBits  = 0xfffffffffffffffc
instruction->bits->highBits = 0x00000000000001fc
instruction->bits->reserved = 0x0000000000000000

instruction->configuration->data     = 0x3fffffffffffffff
instruction->configuration->addr     = 0x000000000000007f
instruction->configuration->type     = 0x0000000000000000
instruction->configuration->reserved = 0x0000000000000000
instruction->bits->lowBits  = 0xfcffffffffffffff
instruction->bits->highBits = 0x0004010000000000
instruction->bits->reserved = 0x000000000000001f

instruction->configuration->data     = 0x3cffffffffffffff
instruction->configuration->addr     = 0x0000000000000003
instruction->configuration->type     = 0x0000000000000000
instruction->configuration->reserved = 0x0003f00400000000