3 回答
TA贡献1842条经验 获得超12个赞
这是用于编译时检查
您可以使用来自boost头文件的信息,该文件endian.hpp涵盖许多平台。
编辑以进行运行时检查
bool isLittleEndian()
{
short int number = 0x1;
char *numPtr = (char*)&number;
return (numPtr[0] == 1);
}
创建一个整数,并读取其第一个字节(最低有效字节)。如果该字节为1,则系统为小端,否则为大端。
编辑思考
是的,您可能会在某些平台(想不到)中遇到潜在问题sizeof(char) == sizeof(short int)。您可以使用可在中使用的固定宽度的多字节整数类型<stdint.h>,或者如果您的平台不提供这种类型,则可以再次使用boost标头供您使用:stdint.hpp
TA贡献1863条经验 获得超2个赞
为了回答最初的编译时检查问题,没有一种标准化的方法可以在所有现有和将来的所有编译器中使用,因为现有的C,C ++和POSIX标准都没有定义用于检测字节序的宏。
但是,如果您愿意将自己局限于某些已知的编译器集,则可以查阅这些编译器的每个文档,以找出它们用于定义字节序的预定义宏(如果有)。 该页面列出了您可以查找的几个宏,因此下面的代码适用于这些宏:
#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \
defined(__BIG_ENDIAN__) || \
defined(__ARMEB__) || \
defined(__THUMBEB__) || \
defined(__AARCH64EB__) || \
defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__)
// It's a big-endian target architecture
#elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \
defined(__LITTLE_ENDIAN__) || \
defined(__ARMEL__) || \
defined(__THUMBEL__) || \
defined(__AARCH64EL__) || \
defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__)
// It's a little-endian target architecture
#else
#error "I don't know what architecture this is!"
#endif
如果您无法从编译器的文档中找到编译器使用的预定义宏,则也可以尝试强制其吐出其预定义宏的完整列表,然后从那里猜测将起作用(使用ENDIAN,ORDER或处理器查找任何内容)架构名称)。 本页列出了许多在不同的编译器中执行此操作的方法:
Compiler C macros C++ macros
Clang/LLVM clang -dM -E -x c /dev/null clang++ -dM -E -x c++ /dev/null
GNU GCC/G++ gcc -dM -E -x c /dev/null g++ -dM -E -x c++ /dev/null
Hewlett-Packard C/aC++ cc -dM -E -x c /dev/null aCC -dM -E -x c++ /dev/null
IBM XL C/C++ xlc -qshowmacros -E /dev/null xlc++ -qshowmacros -E /dev/null
Intel ICC/ICPC icc -dM -E -x c /dev/null icpc -dM -E -x c++ /dev/null
Microsoft Visual Studio (none) (none)
Oracle Solaris Studio cc -xdumpmacros -E /dev/null CC -xdumpmacros -E /dev/null
Portland Group PGCC/PGCPP pgcc -dM -E (none)
最后,要解决这个问题,Microsoft Visual C / C ++编译器很奇怪,没有上述任何内容。幸运的是,它们已经在此处记录了预定义的宏,您可以使用目标处理器体系结构来推断字节序。尽管所有在Windows中目前支持的处理器是小端(_M_IX86,_M_X64,_M_IA64,和_M_ARM是小端),喜欢的PowerPC一些历来支持处理器(_M_PPC)为大端。但更相关的是,Xbox 360是一台大端的PowerPC机器,因此,如果您要编写跨平台的库标头,则可以轻松地进行检查_M_PPC。
TA贡献1836条经验 获得超13个赞
使用C99,您可以执行以下检查:
#define I_AM_LITTLE (((union { unsigned x; unsigned char c; }){1}).c)
类似的条件if (I_AM_LITTLE)将在编译时进行评估,并允许编译器优化整个块。
对于这是否严格来说是C99中的一个常数表达式(这将使它可以用于静态存储持续时间数据的初始化程序),我没有合适的参考资料,但是如果没有,这是下一个最好的选择。
- 3 回答
- 0 关注
- 769 浏览
添加回答
举报