最直观的大小端判断方法是用union:写入int值1后读取低字节char,若为1则是小端,否则为大端;指针转换更轻量但有未定义行为风险;编译期优先用__BYTE_ORDER__宏或C++20的std::endian。
union 判断大小端最直观联合体所有成员共享同一块内存,写入 int 后读取低字节的 char,就能直接看到字节序。这是最常被教、也最不容易出错的方法。
int 值 1(二进制为 0x00000001),它在内存中占 4 字节1(即 char 成员值为 1),说明最低有效字节在前 → 小端0,说明最高有效字节在前 → 大端union {
uint32_t i;
uint8_t c[4];
} u;
u.i = 1;
bool is_little_endian = (u.c[0] == 1);
把 int* 强转成 char*,再取首字节,逻辑和联合体一致,但少了类型安全检查。
reinterpret_cast 并用 volatile 或 memcpy 替代可规避警告,但日常检测用途影响极小uint32_t val = 1; bool is_little_endian = (*reinterpret_cast(&val) == 1);
__BYTE_ORDER__ 宏运行时检测每次都要执行,而多数场景只需要编译时知道端序——比如序列化格式、内存布局或 SIMD 对齐

__BYTE_ORDER__ 是 GCC/Clang 提供的标准宏,值为 __ORDER_LITTLE_ENDIAN__ 或 __ORDER_BIG_ENDIAN__
_M_IX86 / _M_X64 等组合推断(x86/x64 默认小端)std::endian(需 ),但 MSVC 2019 及更早版本不支持#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
// 小端逻辑
#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
// 大端逻辑
#endif
有人会把网络包数据 memcpy 到含 uint16_t/uint32_t 的结构体,指望字段自动按端序解析——这非常危险。
struct 也可能因 padding 导致字段偏移错位ntohs/ntohl 或手动移位拼接(如 (data[0] )
联合体和指针方案只适合“探测”,不能替代规范的字节流解析逻辑。