当年我们做协议。
做二进制。
总会遇到一个瞬间。
我想把这段比特。
当成另一个类型看。
当年:union type punning 很常见,也很危险
你可能见过这种写法。
union U {
float f;
unsigned int u;
};
U x;
x.f = 1.0f;
auto bits = x.u;
它在很多编译器上能跑。
但严格来说。
这类写法踩在未定义行为边缘。
线上最怕这种“边缘”。
C++20:std::bit_cast
bit_cast 做的事很明确。
按位复制。
不做数值转换。
#include <bit>
#include <cstdint>
float f = 1.0f;
std::uint32_t u = std::bit_cast<std::uint32_t>(f);
这行代码的意思是。
我只是想看比特。
不是想把 1.0 转成整数 1。
线上啪一下:大小端写反,协议字段全错
另一类常见事故。
是大小端。
你在 x86 上测试。
都对。
到某个平台。
字段全反。
你才想起。
世界不是只有小端。
C++20:std::endian
std::endian 给你一个类型化的判断。
#include <bit>
static_assert(std::endian::native == std::endian::little ||
std::endian::native == std::endian::big);
你可以在编译期做分支。
而不是靠平台宏。
关键结论
位级代码最怕“看起来能跑”。
要么明确。
要么迟早炸。
小结
bit_cast 让位转换更像工具。
endian 让大小端判断更像规则。
它们都在替你减少“靠运气”的代码。