Is C Endian neutral?

时间:2016-02-12 20:36:35

标签: c endianness translate

Is C endian-neutral? Ok, another way of asking this question. I am currently translating a lot of code from C to Matlab on the same platform (PC). Do I need to care about endianess? Both are endian-neutral languages but C (not so sure), Matlab (pretty sure). By the same token I am also translating C to Python. So my question, has anybody in his experience, (translating from C to another endian-neutral language) met an unexpected problem with big/little endianness. Obviously we are only speaking about the core language. In this case I mentionned C99.

1 个答案:

答案 0 :(得分:2)

首先,一些背景和澄清:

正如我在对原始问题的评论中提到的,字节顺序经常与位顺序混淆。字节顺序仅指字节顺序。位顺序仅与文档相关,并且通过某些串行连接发送数据时。

在算术中,在base B (和2≤ B εℕ)中, i ' D i 具有值 D i B i 。最低有效位数对应于 i = 0,即 D 0 。对于二进制, B = 2.对于大多数人喜欢的普通十进制数, B = 10。

(这适用于所有实数,而不仅仅是整数。最重要的小数位,小数点另一侧的第一个数字,是 D -1 ,更负面的 i 表示不太有效的数字。)

因为' bit'因此,我们有一个自然标记的方式,其中位0表示最低有效(整数)位(对应于值1),位1指的是有意义的下一个(对应于值2),依此类推。

使用big-endian字节顺序的硬件的一些文档坚持将单词中最重要的位标记为" bit 0" (位数从左到右增加 - 与大多数数字表示相反,数字从右到左变得更加显着)。这只是一个标签约定,因为该约定不遵循算术规则。实际上,你需要知道那个单词的宽度(位数),甚至可以计算出这个" bit 0" s的实际数值。

  

C endian-neutral?

是,C(在ISO C89,C99和C11中)在字节顺序方面是中性的。标准没有定义任何字节顺序;由实施来决定。实际上,编译器在编译时选择适合目标体系结构的字节顺序。

理论上,整数和浮点类型可能具有不同的字节顺序。

POSIX.1为C添加网络支持。网络相关结构中的某些字段定义为网络字节顺序,最重要的字节优先。 POSIX.1提供htons()htonl()ntohs()ntohl() byteorder函数,以便从主机转换为网络字节顺序,反之亦然。

除了网络字节顺序(通常称为 big-endian )之外,小端字节顺序(最低有效字节优先)也很常见,例如在Intel / AMD架构上。 PDP-endian 字节顺序(其中四字节值首先存储在第二最高有效字节,然后是最高有效字节,后跟最低有效字节,后跟第二最低有效字节)现在很少见。

最后,C已经在大量架构上实现,其中字节顺序涵盖了上面提到的所有三个,没有任何字节顺序问题。这应该足够实用。

  

我目前正在同一平台(PC)上将大量代码从C转换为Matlab [或Python]。我需要关心结束吗?

不,在C,Matlab,Python或任何高级语言之间移植代码时,我都没有理由关心字节顺序。

然而:

语言是字节序中立的并不意味着您不需要关心程序中的字节顺序。 数据字节顺序很重要。它归结为您的程序如何传输 - 读取和写入 - 数据;通过内存结构(使用共享内存,或通过库绑定在不同的编程语言之间),文件,网络连接或通过/到其他程序的管道。

如果您的程序以某种基于文本的格式传输数据,那么您需要担心的是该格式,以及可能使用的字符集 - 我更喜欢UTF-8(请参阅utf8everywhere.org

如果你的程序以二进制形式传输数据,那么你必须明白,在二进制中,多字节值总是具有一些特定的字节顺序。它可以是当前体系结构的网络字节顺序(或大端),小端或本机字节顺序。仅仅因为你的编程语言是字节序中立的,并不意味着你会忽略存储字节顺序。

例如,Matlab和Octave fread()支持第五个参数,该参数指定使用的字节顺序:nativeieee-be(IEEE big-endian)或ieee-le( IEEE little-endian)。 Python struct模块打包和解包函数默认为本机字节顺序和C对齐(填充),但您可以使用<>作为格式字符串中的第一个字符来表示 - 没有填充的endian或big-endian / network-endian字节顺序。

C代码以本机字节顺序存储二进制数据是很常见的。但是,有些C代码没有。我更喜欢以本机字节顺序存储,但也存储每种不同基本数字类型的已知原型值,以便读者可以轻松检测是否需要置换字节顺序以正确解释代码。还有各种库和格式,如NetCDF,可用于创建可移植的二进制数据文件。

最重要的是首先要了解C代码的作用。

我不明白为什么有人会想要将代码从C语言移植到Matlab或Python,除非C代码开头真的很差 - 在这种情况下我只是重写< / em>逻辑,而不是移植现有代码。

  

您是否遇到了大/小字节序的意外问题?

不,从不在高级语言之间移植代码。

是,在不同系统之间存储/检索二进制数据时。

虽然与字节序无关,但对于多维数据,重要的是要记住Fortran和Matlab(和OpenGL矩阵)使用列主要顺序(每列在内存中是连续的),而C使用行主顺序(每行在内存中连续)。