(这个问题来自昨天向某人解释CHAR_BIT,sizeof和endianness的细节。这完全是假设的。)
假设我在一个CHAR_BIT为32的平台上,所以sizeof(char)== sizeof(short)== sizeof(int)== sizeof(long)。我相信这仍然是一个符合标准的环境。
在运行时(because there is no reliable way to do it at compile time)检测字节顺序的常用方法是创建union { int i, char c[sizeof(int)] } x; x.i = 1
并查看是否设置了x.c[0]
或x.c[sizeof(int)-1]
。
但是这在这个平台上不起作用,因为我最终得到了一个char [1]。
有没有办法在运行时检测这样的平台是big-endian还是little-endian?显然,在这个假设系统中没有关系,但可以想象它正在写入一个文件,或某种内存映射区域,另一台机器根据其(更精确的)内存模型读取并重建它。
答案 0 :(得分:4)
假设,在所有数据类型大小相同的环境中,没有字节顺序。
我可以看到三种可能性:
如果限制仅由C编译器提供,并且从技术上讲,平台有一些较小的数据类型,则可以使用汇编程序来检测字节序。
如果平台支持双数据类型,您可以使用它来检测字节序,因为它总是64位宽。
您也可以按照建议将数据写入文件,然后回读。只需编写两个字符(二进制模式下的文件),将文件指针移动到位置1并读回一个字符。
答案 1 :(得分:4)
字节序的概念仅对由多个字节表示的标量类型有意义。根据定义,char
是单字节的,因此任何与char
具有相同大小的整数类型都没有字节序。
还要记住,不同类型的字节顺序可能不同:例如,PDP-11是一个小端16位架构,32位整数是由两个16位小端值构建的,结束混合端。
答案 2 :(得分:2)
我认为这个问题归结为:字节序在这个平台上是一个有意义的概念,即它是否对程序的行为有可检测的影响?
如果没有,那么字节顺序(即构成32位数量的单个字节存储在内存中的顺序)仅仅是一个你无法检测但不需要考虑的实现细节。你要么。
如果字节序确实对语言的某个方面的行为有可检测的影响......那么,然后根据该行为构建测试。以下是一些例子:
平台上的寻址系统如何工作?如果将地址递增1,那么对应的位数是多少?如果答案是8位且系统允许您从不是4的倍数的地址读取,那么您可以将指针向前移动一个字节(通过绕道到intptr_t
)并测试字节顺序那样。 (是的,这是实现定义的行为,但是使用union来测试endianness以及一般的endianness的整个概念。)但是,如果内存的最小可寻址单位是32字节,那么你可以'以这种方式测试字节顺序。
平台是否具有64位数据类型(long long
)?然后,您可以创建long long
和两个int
的联合,并根据该联合构建您的字节顺序测试。
答案 3 :(得分:0)
结构位域仍然可以在任何平台上正常工作,即使是这个:
union {
int i;
struct {
int b1 : 8;
int b2 : 8;
int b3 : 8;
int b4 : 8;
} s;
} u;
u.i = 1;
if (u.s.b1 != 0)
....
答案 4 :(得分:0)
这个问题没有提供足够的信息,但它提供了什么,我会说:不可能。
答案 5 :(得分:0)
htonl
应该有效:
if(htonl(1)==1) {
/* network order (big-endian) */
} else {
/* little-endian */
}
(我看不出有任何理由不以通常的方式实施htonl
和朋友,即使对于这个讨厌的假设系统 - 尽管我不确定他们会有多少帮助做法。)
答案 6 :(得分:0)
您可以移动有问题的变量,看看1的哪一端移开。
答案 7 :(得分:-1)
如果你的代码依赖于知道架构是BE还是LE,那么你的代码应该具有安全性,而不是针对未知平台进行编译。有些#if ! defined(ARCH_IS_LE) && ! defined(ARCH_IS_BE) \ #error unknown architecture
应该这样做。