C语言 在32位架构上,我是否需要处理8位位字段结构体的字节序?

pjngdqdw  于 2023-06-05  发布在  其他
关注(0)|答案(2)|浏览(221)

我正在32位架构(准确地说是AVR32)上做一些嵌入式软件。在此软件上,我从通过I2C连接的外部外围设备中检索一个标记(编码为一个字节)。
这个字节的每一位都是一个布尔变量。结构如下:

typedef union __attribute__((packed)){
  struct __attribute__((packed)) {
    uint8_t flag_a : 1;
    uint8_t flag_a : 1;
    uint8_t flag_a : 1;
    uint8_t flag_a : 1;
    uint8_t flag_a : 1;
    uint8_t __unused : 3;
  }
  uint8_t raw;
}Flag_t;

我的问题是,如果我想让这段代码可移植,我是否需要在联合体内部以相反的顺序重新定义另一个字节序的结构体?
或者,在这种情况下是否不存在字节序问题?

iih3973s

iih3973s1#

如果我想让这段代码可移植
然后不要使用位域。使用位操作。
另一个字节序的顺序是相反的
是的,但这是 * 编译器特定的 *,即。不便携。在gcc上你可以使用Bitfield endianness in gcc
在这种情况下是否不存在字节序问题?
是的,但不仅如此-编译器可以在结构成员之间插入任何填充,uint8_t可能 * 不 * 支持位字段,并且编译器选择在字节内进行位的“endianness”。

k5ifujac

k5ifujac2#

Endianness只是多字节变量的问题,因此在您的情况下不是问题。
然而,位字段的使用对于可移植性而言是潜在的问题。C标准将其留给编译器实现来决定如何实现它们。因此,不能期望它们在不同的环境中表现相同。
更好的选择是使用单个字节并定义不同位的含义。例如:

typedef uint8_t Flag_t;
   typedef enum
   {
      flag_a = 1u << 0,
      flag_b = 1u << 1,
      flag_c = 1u << 2,
      flag d = 1u << 3,
      flag e = 1u << 4,
   } Flag_Bits_t;

相关问题