gpt4 book ai didi

c - 检测字节顺序

转载 作者:太空狗 更新时间:2023-10-29 16:29:06 25 4
gpt4 key购买 nike

我目前正在尝试创建一个 C 源代码,无论目标系统的字节顺序如何,它都能正确处理 I/O。

我选择了“小端”作为我的 I/O 约定,这意味着,对于大端 CPU,我需要在写入或读取时转换数据。

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

到目前为止,我一直在使用这个:

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

它被记录为 GCC 预定义的宏,Visual 似乎也能理解它。

但是,我收到了一些 big_endian 系统 (PowerPC) 检查失败的报告。

因此,我正在寻找一种万无一失的解决方案,无论编译器和目标系统是什么,它都能确保正确检测字节顺序。好吧,他们中的大多数人至少......

[编辑]:提出的大多数解决方案都依赖于“运行时测试”。这些测试有时可能会在编译期间由编译器正确评估,因此不会消耗真正的运行时性能。

但是,使用某种 <<if (0) { ... } else { ... } >> 进行分支是不够的。在目前的代码实现中,变量和函数的声明依赖于big_endian检测。这些不能用 if 语句更改。

嗯,很明显,有回退计划,就是重写代码...

我宁愿避免这种情况,但是,好吧,这看起来希望渺茫......

[编辑 2]:我通过深度修改代码测试了“运行时测试”。尽管他们正确地完成了工作,但这些测试也会影响性能。

我原以为,由于测试具有可预测的输出,编译器可以消除错误的分支。但不幸的是,它并不总是有效。 MSVC 是一个很好的编译器,并且成功地消除了错误的分支,但是 GCC 的结果好坏参半,这取决于版本、测试类型,并且对 64 位的影响比对 32 位的影响更大。

这很奇怪。这也意味着无法确保编译器处理运行时测试。

编辑 3:最近,我正在使用编译时常量 union ,期望编译器将其解决为明确的是/否信号。它工作得很好: https://godbolt.org/g/DAafKo

最佳答案

如前所述,检测 Big Endian 的唯一“真正”方法是使用运行时测试。

但是,有时可能更喜欢使用宏。

不幸的是,我没有找到一个单一的“测试”来检测这种情况,而是找到了它们的集合。

例如,GCC 推荐:__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__。然而,这只适用于最新版本,早期版本(和其他编译器)会给这个测试一个假值“真”,因为 NULL == NULL。所以你需要更完整的版本:defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)

好的,现在这适用于最新的 GCC,但其他编译器呢?

您可以尝试 __BIG_ENDIAN____BIG_ENDIAN_BIG_ENDIAN,它们通常在大端编译器上定义。

这将改进检测。但是,如果您专门针对 PowerPC 平台,则可以添加更多测试以改进更多检测。尝试 _ARCH_PPC__PPC____PPCPPC__powerpc____powerpc 甚至 powerpc。将所有这些定义绑定(bind)在一起,您就有相当大的机会检测大端系统,尤其是 powerpc,无论编译器及其版本如何。

因此,总而言之,不存在保证在所有平台和编译器上检测大端 CPU 的“标准预定义宏”之类的东西,但是有许多这样的预定义宏,它们共同提供在大多数情况下正确检测大端字节序的可能性很高。

关于c - 检测字节顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8978935/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com