我以前写过一个网络解析。
代码没崩。
但数据总是不对。
你抓包对了。
你打印也对了。
就是最后算出来不对。
后来发现。
我把“字节”当成了“字符”。
当年:C 里 byte 没有专门的类型,大家就用 char
C 里最方便的 1 字节类型是 char。
所以很多代码写成。
unsigned char buf[16];
问题在于。
char 这个词太像“字符”。
很多函数也把它当字符。
你一不小心就把二进制数据喂给了字符串函数。
线上啪一下:我拿二进制包去 strlen,长度直接变玄学
假设你拿到一个二进制消息。
里面可能有 0 字节。
你如果写。
const char* p = reinterpret_cast<const char*>(buf);
size_t n = std::strlen(p); // ❌
strlen 会在第一个 \0 停下来。
你以为你在算长度。
其实你在找运气。
C++17:std::byte,明确它只用于原始字节
#include <cstddef>
std::byte buf[16]{};
std::byte 的意思很克制。
它不代表字符。
也不代表数字。
它就是一块字节。
你要把它当成整数。
必须显式转换。
#include <cstddef>
#include <cstdint>
std::uint8_t x = std::to_integer<std::uint8_t>(buf[0]);
这句看起来麻烦。
但它能救你。
因为它逼你确认。
“我现在是在解释这段内存。”
位运算:std::byte 只允许你做你该做的事
std::byte 支持位运算。
std::byte b{0x1};
b <<= 1;
它不支持加减乘除。
因为那会把它变成“数”。
标准库在这里的态度是。
别让你顺手乱用。
关键结论
std::byte 的意义不是新能力。
它是新边界:这不是字符,不要拿它当字符串。
小结:把二进制和文本分开,你会少掉一堆奇怪 bug
当年用 char 表示字节。
最可怕的不是写不出来。
是别人读代码时会误解。
C++17 给了 std::byte。
它像一个路牌。
提醒你。
这里是原始数据。
别用字符的眼光去看。