不要使用union!
C++ 不允许通过unions 进行类型双关语!
从不是最后写入的字段的联合字段中读取是未定义的行为!
许多编译器支持这样做作为扩展,但语言不保证。
查看此答案了解更多详情:
https://stackoverflow.com/a/11996970
只有两个有效的答案可以保证是可移植的。
第一个答案,如果你可以访问支持 C++20 的系统,
是使用 <type_traits> 标头中的 std::endian。
(在撰写本文时,C++20 尚未发布,但除非发生某些事情会影响 std::endian 的包含,否则这将是在 C++ 编译时测试字节顺序的首选方法20 起。)
C++20 以后
constexpr bool is_little_endian = (std::endian::native == std::endian::little);
在 C++20 之前,唯一有效的答案是存储一个整数,然后通过类型双关语检查它的第一个字节。
与使用 unions 不同,这是 C++ 的类型系统明确允许的。
同样重要的是要记住,为了获得最佳便携性,应该使用static_cast,
因为reinterpret_cast 是实现定义的。
如果程序尝试通过非以下类型之一的左值访问对象的存储值,则行为未定义:
...
char 或 unsigned char 类型。
C++11 以后
enum class endianness
{
little = 0,
big = 1,
};
inline endianness get_system_endianness()
{
const int value { 0x01 };
const void * address = static_cast<const void *>(&value);
const unsigned char * least_significant_address = static_cast<const unsigned char *>(address);
return (*least_significant_address == 0x01) ? endianness::little : endianness::big;
}
C++11 以后(无枚举)
inline bool is_system_little_endian()
{
const int value { 0x01 };
const void * address = static_cast<const void *>(&value);
const unsigned char * least_significant_address = static_cast<const unsigned char *>(address);
return (*least_significant_address == 0x01);
}
C++98/C++03
inline bool is_system_little_endian()
{
const int value = 0x01;
const void * address = static_cast<const void *>(&value);
const unsigned char * least_significant_address = static_cast<const unsigned char *>(address);
return (*least_significant_address == 0x01);
}