(我猜这个问题适用于许多编程语言,但我选择以C++作为例子。)
为什么不能只写:
struct foo {
little int x; // little-endian
big long int y; // big-endian
short z; // native endianness
};
如何指定特定成员、变量和参数的字节序?
与有符号性的比较
我理解一个变量的类型不仅决定了用多少字节来存储一个值,还决定了在执行计算时如何解释这些字节。
例如,以下两个声明都分配了一个字节,对于这两个字节,每个可能的8位序列都是一个有效值:
signed char s;
unsigned char u;
但是相同的二进制序列可能会有不同的解释,例如11111111
在分配给s
时表示-1,但在分配给u
时表示255。当涉及到有符号和无符号变量在同一计算中时,编译器(大多数情况下)会处理正确的转换。
在我看来,字节顺序只是相同原理的一种变化:基于编译时关于将存储在其中的内存的信息的不同解释。这似乎在允许低级编程的类型语言中很明显。但是,这不是我知道的任何语言,也没有在网上找到任何相关讨论。
更新
我将尝试总结一些我在发帖后第一个小时得到的评论:
- 签名是严格二进制的(有符号或无符号),并且永远都是这样的,与字节顺序形成对比,后者也有两个众所周知的变体(big和little),还有一些较少知名的变体,例如mixed/middle endian。未来可能会发明新变体。
- 字节顺序对按字节访问的多字节值的访问方式很重要。除了字节顺序之外,还有许多因素影响多字节结构的内存布局,因此通常不建议使用这种访问方式。
- C++旨在针对抽象机器进行定位,并尽量减少对实现的假设。这个抽象机器没有任何字节顺序。
此外,我现在意识到,签名和字节顺序并不是完美的类比,因为:
- 字节顺序仅定义了如何将某些东西表示为二进制序列,但不定义可以表示什么。两个
big int
和little int
将具有完全相同的值范围。 - 签名定义了如何映射位和实际值之间的关系,但也影响可以表示的内容,例如-3无法用
unsigned char
表示,而(假设char
具有8位)130无法用signed char
表示。
因此,更改某些变量的字节顺序永远不会改变程序的行为(除了按字节访问),而更改签名通常会。