char isa_storage[sizeof(isa_t)];
首先,只是在内存里申请了 8 个字节,内容是什么不重要,就是一块原始内存。
0x1000 ← isa_storage 的起始地址
此时这 8 字节只是 char[8],没有任何结构。
reinterpret_cast<isa_t *>(isa_storage)
isa_storage 作为数组名,自动退化成指向首字节的指针 char* = 0x1000。
char* 0x1000
──reinterpret_cast──▶
isa_t* 0x1000
地址值没变,还是 0x1000。
只是告诉编译器:请把这个地址当作 isa_t* 来用。
运行时没有任何指令执行,零开销。
0x1000 ← 现在编译器把这里当作 isa_t* 指向的对象
*reinterpret_cast<isa_t *>(isa_storage)
对 isa_t* 做 * 解引用,得到 isa_t&(引用)。
isa_t* 0x1000
──*解引用──▶
isa_t& (原地)
引用 = 原来那块内存的别名,没有拷贝,没有新内存。
就像给那 8 字节起了个名字叫 isa_t。
isa_t &isa() { return *reinterpret_cast<isa_t *>(isa_storage); }
函数返回这个 isa_t&,调用者就能直接用 isa_t 的成员了:
isa().bits
isa().cls
isa().nonpointer // 位域直接访问
整个过程只是"换了一副眼镜去看同一块内存",字节本身从来没有移动过。