为什么结构字节中位字段的顺序不是由语言本身定义的?
Why is the order of bit fields in the bytes of structs not defined by the language itself?
我今天遇到了一个问题,我发现字节中的位字段的排序方式取决于处理器的字节顺序。举下一个例子:
struct S {
uint8_t a : 3;
uint8_t b : 5;
};
此结构占用一个字节,但位布局取决于机器:
- 小端:b4 b3 b2 b1 b0 a2 a1 a0
- 大端:a2 a1 a0 b4 b3 b2 b1
因此,在小端机器上,它从 LSB 开始填充,而在大端机器上,它从 MSB 开始填充。我曾经听 Stroustrup 说实现跨平台的可移植性是一个主要目标,但是留下一些这样的东西根本不可移植。如果我通过连接将这个结构发送给某人,他怎么知道哪些位映射到结构中的哪些字段?如果订单是固定的不是更容易吗?选择对处理器和编译器开放的原因是什么?唯一安全的选择是使用使用更多代码的位移位和掩码。如果我和我的同事可以指望一个固定的顺序,例如小端方式,那会容易得多,但肯定有一个选择不这样做的原因。
它们不是由语言定义的,因此它可以适应您发现的确切情况。对于一个字节中的位域没有区别,但位域可以占用更大的整数类型。考虑这个例子:
struct bf
{
uint16_t a : 5;
uint16_t b : 11;
};
为了使字段的位在内存中相邻,字节 中的位必须 根据处理器的字节顺序进行不同的布局。
大端:
aaaaabbb bbbbbbbb
小端:
bbbbbbbb bbbaaaaa
我今天遇到了一个问题,我发现字节中的位字段的排序方式取决于处理器的字节顺序。举下一个例子:
struct S {
uint8_t a : 3;
uint8_t b : 5;
};
此结构占用一个字节,但位布局取决于机器:
- 小端:b4 b3 b2 b1 b0 a2 a1 a0
- 大端:a2 a1 a0 b4 b3 b2 b1
因此,在小端机器上,它从 LSB 开始填充,而在大端机器上,它从 MSB 开始填充。我曾经听 Stroustrup 说实现跨平台的可移植性是一个主要目标,但是留下一些这样的东西根本不可移植。如果我通过连接将这个结构发送给某人,他怎么知道哪些位映射到结构中的哪些字段?如果订单是固定的不是更容易吗?选择对处理器和编译器开放的原因是什么?唯一安全的选择是使用使用更多代码的位移位和掩码。如果我和我的同事可以指望一个固定的顺序,例如小端方式,那会容易得多,但肯定有一个选择不这样做的原因。
它们不是由语言定义的,因此它可以适应您发现的确切情况。对于一个字节中的位域没有区别,但位域可以占用更大的整数类型。考虑这个例子:
struct bf
{
uint16_t a : 5;
uint16_t b : 11;
};
为了使字段的位在内存中相邻,字节 中的位必须 根据处理器的字节顺序进行不同的布局。
大端:
aaaaabbb bbbbbbbb
小端:
bbbbbbbb bbbaaaaa