关于C++序列化中位操作与大小端检测的疑问
关于序列化教程中字节序实现与检测的疑问确认
一、序列化encode函数的字节序问题
我学习的序列化教程中,作者通过std::vector<int8_t>逐字节写入整数类型,以int32_t值76745为例,写入后vector内容为{0, 1, 43, -55}。作者提供的核心实现简化后如下:
template <typename T> void encode(std::vector<int8_t> *buffer, int16_t *iterator, T value) { for (size_t i = 0; i < sizeof(T); ++i) { (*buffer)[(*iterator)++] = value >> ((sizeof(T) * 8 - 8) - i*8); } }
作者声称这段代码是将数字转换为小端字节序,但这个说法明显错误:
- 位移操作是针对整数的数值二进制逻辑进行的,和机器内存中的字节存储顺序(字节序)无关。无论当前机器是大端还是小端,
value作为一个整数类型,其数值是确定的,位移运算的结果只和数值本身有关。 - 以
int32_t为例,循环中每次的位移量分别是24、16、8、0,这意味着代码会依次取出value的最高字节、次高字节、第三字节、最低字节写入vector,最终vector中的字节顺序是高字节在前,低字节在后,这是标准的大端字节序,和作者声称的小端完全相反。
二、字节序检测函数的错误
作者提供的字节序检测代码同样存在逻辑错误:
bool IsLittleEndian() // weirdest { int8_t a = 5; std::string res = std::bitset<8>(a).to_string(); std::cout << res << '\n'; return (res.back() == '1'); }
这段代码完全无法检测字节序,理由如下:
- 字节序是多字节类型在内存中的存储顺序,
int8_t是单字节类型,不存在字节序的概念,用单字节变量检测字节序从逻辑上就不成立。 std::bitset::to_string()的输出是从二进制的最高位到最低位排列,比如数值5的二进制是00000101,转换后的字符串是"00000101",back()取到的是最低位的'1',但这和字节序没有任何关系——不管机器是大端还是小端,单字节的二进制表示都是固定的。- 正确的字节序检测应该利用多字节类型,比如定义一个
uint32_t变量赋值为1,然后通过指针访问其第一个字节(内存低地址处的字节),如果该字节的值是1,则为小端;如果是0,则为大端。
内容的提问来源于stack exchange,提问作者Synthwave09
相关产品推荐
相关产品推荐

