我想知道编写endianess独立代码的最佳方法是什么,尤其是在使用数组“test_attr [0] / test_attr [1]”访问位字段时??
struct tagTest
{
union
{
struct
{
uint16 A:3;
uint16 B:3;
uint16 C:3;
uint16 D:3;
uint16 E:3;
uint16 F:1;
uint16 G:3;
uint16 H:3;
uint16 I:3;
uint16 J:3;
uint16 K:4;
} Attributes;
uint16 test_attr[2];
} EndianIndependent;
};
答案 0 :(得分:2)
在某些来源中使用以下方式:
struct
{
#if BYTE_ORDER == LITTLE_ENDIAN
uint16 A:4;
uint16 B:4;
uint16 C:4;
uint16 D:4;
#endif
#if BYTE_ORDER == BIG_ENDIAN
uint16 D:4;
uint16 C:4;
uint16 B:4;
uint16 A:4;
#endif
} Attributes;
但它看起来真的很难看。也许它不那么便携。 可能最好使用位掩码和位移而不是位文件。
答案 1 :(得分:1)
位字段排序依赖于实现,甚至不需要与目标的基本字节同步。 通过数组访问位字段更依赖于处理器和编译器。
编写独立代码的唯一机会是将访问封装在一组函数中,并在每个编译器/处理器组合上验证是否返回了正确的结果。
我在将代码从Freescale S12X移植到MPC56xx架构时遇到了同样的问题,这些转换非常乏味但不可避免。 MPC甚至以反方向对一个字中的位进行编号。去图!
答案 2 :(得分:0)
这根本不是便携式的,但就我而言,这对我帮助很大:)
#ifdef __LITTLE_ENDIAN
#define BITFIELD2(a,b) a;b;
#elif defined(__BIG_ENDIAN)
#define BITFIELD2(a,b) b;a;
#else
#error cannot decide architecture
#endif
#define BITFIELD3(a,b,c) BITFIELD2(a,BITFIELD2(b,c))
#define BITFIELD4(a,b,c,d) BITFIELD2(a,BITFIELD3(b,c,d))
#define BITFIELD5(a,b,c,d,e) BITFIELD2(a,BITFIELD4(b,c,d,e))
#define BITFIELD6(a,b,c,d,e,f) BITFIELD2(a,BITFIELD5(b,c,d,e,f))
struct
{
BITFIELD6(
uint16 A:3,
uint16 B:3,
uint16 C:3,
uint16 D:3,
uint16 E:3,
uint16 F:1
)
BITFIELD5(
uint16 G:3,
uint16 H:3,
uint16 I:3,
uint16 J:3,
uint16 K:4
)
} Attributes;