我目前正在尝试创建一个C无论目标系统的字节顺序如何,源代码都能正确处理 I/O。
我选择了“little endian”作为我的 I/O 约定,这意味着,对于 big endian 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 位的影响更大。
真奇怪。这也意味着无法确保编译器能够处理运行时测试。
Edit 3:这些天,我使用编译时常量联合,期望编译器将其解决为明确的是/否信号。
而且效果很好:https://godbolt.org/g/DAafKo https://godbolt.org/g/DAafKo