检测字节序 [英] Detecting Endianness

查看:147
本文介绍了检测字节序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在试图创建一个 C 源$ C ​​$ C这妥善处理I / O的任何目标系统的字节序。

I'm currently trying to create a C source code which properly handles I/O whatever the endianness of the target system.

我选择小尾数法作为我的I / O大会,这意味着,对于大端CPU,我需要把数据转换当写或读。

I've selected "little endian" as my I/O convention, which means that, for big endian CPU, I need to convert data while writing or reading.

转换不是问题。我面临的问题是要在编译时pferably检测字节顺序,$ P $(因为CPU不执行过程中更改端...)。

Conversion is not the issue. The problem I face is to detect endianness, preferably at compile time (since CPU do not change endianness in the middle of execution...).

到现在为止,我一直在使用这样的:

Up to now, I've been using this :

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
...
#else
...
#endif

它的记录作为GCC pre-定义的宏和Visual似乎也明白这一点。

It's documented as a GCC pre-defined macro, and Visual seems to understand it too.

不过,我已经收到报告说,在检查一些BIG_ENDIAN系统(PowerPC的)失败。

However, I've received report that the check fails for some big_endian systems (PowerPC).

所以,我正在寻找一个一劳永逸的解决方案,从而确保字节序是否正确检测到,无论编译器和目标系统。同时,他们大多至少...

So, I'm looking for a foolproof solution, which ensures that endianess is correctly detected, whatever the compiler and the target system. well, most of them at least...

:大多数提出的解决方案依赖于运行时的测试。这些测试有时可以适当地由编译器在编译期间进行评估,因此花费没有真正的运行时性能。

: Most of the solutions proposed rely on "run-time tests". These tests may sometimes be properly evaluated by compilers during compilation, and therefore cost no real runtime performance.

然而,随着某种&所述分支;&下; 如果(0){...}其他{...} >>是不够的。在目前的code语言实现,变量和函数的声明取决于BIG_ENDIAN检测。这些不能用一个if语句来改变。

However, branching with some kind of << if (0) { ... } else { ... } >> is not enough. In the current code implementation, variable and functions declaration depend on big_endian detection. These cannot be changed with an if statement.

嗯,很明显,有回落的计划,这是重写code ...

Well, obviously, there is fall back plan, which is to rewrite the code...

我想preFER避免这种情况,但是,嗯,它看起来像一个缩小的希望...

I would prefer to avoid that, but, well, it looks like a diminishing hope...

:我已经测试运行时测试,由深修改code。虽然他们正确地做他们的工作,这些测试也影响性能。

: I have tested "run-time tests", by deeply modifying the code. Although they do their job correctly, these tests also impact performance.

我期待的是,由于测试必须predictable输出,编译器可以消除不良分支机构。但不幸的是,它不工作的所有时间。 MSVC好编译器,并成功地消除不良分支机构,但GCC有不同的结果,这取决于版本,一种测试,并与64位比32位更大的影响。

I was expecting that, since the tests have predictable output, the compiler could eliminate bad branches. But unfortunately, it doesn't work all the time. MSVC is good compiler, and is successful in eliminating bad branches, but GCC has mixed results, depending on versions, kind of tests, and with greater impact on 64 bits than on 32 bits.

这很奇怪。它也意味着在运行时测试不能保证待由编译器来处理。

It's strange. And it also means that the run-time tests cannot be ensured to be dealt with by the compiler.

推荐答案

如前所述,唯一的真正的方法来检测大端是使用运行时测试。

As stated earlier, the only "real" way to detect Big Endian is to use runtime tests.

但是,有时候,宏可能是preferred。

However, sometimes, a macro might be preferred.

不幸的是,我还没有找到一个单一的测试,以检测这种情况,而一个人的集合。

Unfortunately, I've not found a single "test" to detect this situation, rather a collection of them.

例如,GCC建议: __ BYTE_ORDER__ == __ORDER_BIG_ENDIAN __ 。不过,这仅与最新版本及更早版本(和其他编译器)的作品会给这个测试假值真,因为NULL == NULL。因此,你需要更完整的版本:规定(__ __ BYTE_ORDER)及;及(__ BYTE_ORDER__ == __ORDER_BIG_ENDIAN __)

For example, GCC recommends : __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ . However, this only works with latest versions, and earlier versions (and other compilers) will give this test a false value "true", since NULL == NULL. So you need the more complete version : defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)

好了,现在这个工程的最新的GCC,但对于其他的编译器?

OK, now this works for newest GCC, but what about other compilers ?

您可以尝试 __ BIG_ENDIAN __ __ BIG_ENDIAN _BIG_ENDIAN 这通常被定义于大端编译器。

You may try __BIG_ENDIAN__ or __BIG_ENDIAN or _BIG_ENDIAN which are often defined on big endian compilers.

这将提高检测。但是,如果你专门针对PowerPC的平台上,可以添加一些更多的测试,以提高更检测。尝试 _ARCH_PPC __ PPC __ __ PPC PPC __的PowerPC __ __的PowerPC 甚至的PowerPC 。绑定所有这些定义在一起,和你有一个pretty公平的机会来检测大端系统,以及PowerPC特别,无论编译器和它的版本。

This will improve detection. But if you specifically target PowerPC platforms, you can add a few more tests to improve even more detection. Try _ARCH_PPC or __PPC__ or __PPC or PPC or __powerpc__ or __powerpc or even powerpc. Bind all these defines together, and you have a pretty fair chance to detect big endian systems, and powerpc in particular, whatever the compiler and its version.

因此​​,要总结,有作为保证来检测所有的平台和编译器大端CPU标准pre定义的宏没有这样的事,但也有许多规定对这样的$ P $宏其中,集体,给予在大多数情况下正确检测大端的概率高。

So, to summarize, there is no such thing as a "standard pre-defined macros" which guarantees to detect big-endian CPU on all platforms and compilers, but there are many such pre-defined macros which, collectively, give a high probability of correctly detecting big endian under most circumstances.

这篇关于检测字节序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆