You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

《The C++ Programming Language》中union避免类型转换的原理问询

解答:用Union避免类型转换获取空指针的内存表示

嘿,这个问题问得好!我来帮你拆解一下Stroustrup在《The C++ Programming Language》里提到的这个union用法,到底是怎么做到“避免类型转换”的。

首先,先还原书中提到的Fudge union的典型写法,大概是这样的:

union Fudge {
    void* p;    // 指针类型成员
    long i;     // 整数类型成员
};

为什么用Union能避免类型转换?

要理解这点,我们先对比不用union的写法:如果想获取空指针(指针0)的内存表示,你通常需要用显式的类型转换,比如:

// 用reinterpret_cast做显式类型转换
long null_ptr_representation = reinterpret_cast<long>(nullptr);

这里的reinterpret_cast就是典型的类型转换操作,它明确告诉编译器“我要把一个指针类型转换成整数类型”。

而用Fudge union的话,写法是这样的:

Fudge f;
f.p = nullptr;  // 给指针成员赋值为空指针(即指针0)
long null_ptr_representation = f.i;  // 直接读取整数成员的值

你看,这里完全没有用到任何类型转换操作符(比如reinterpret_cast、C风格的(long)强制转换),只是通过union的成员访问,直接从同一块内存里读出了另一种类型的值。

核心原理:Union的内存共享特性

Union的本质是所有成员共享同一块内存空间——也就是说,f.p和f.i占用的是内存中完全相同的字节。当你给f.p赋值为nullptr时,内存里会写入空指针对应的字节序列;之后读取f.i,就是把这些字节序列直接解释成long类型的值。

这种方式相当于“绕过”了显式类型转换的语法,让你在不同类型之间访问同一块内存,而不需要写转换操作符——这就是Stroustrup说的“刻意使用union来避免类型转换”的核心意思。

补充:C++标准里的注意事项

虽然这种union类型双关的用法在C里很普遍,在C里也被很多编译器支持,但严格来说,C标准对这种“写一个成员读另一个成员”的行为有一定限制(仅对某些POD类型或布局兼容类型是合法的)。不过对于指针和整数这种常见场景,主流编译器(GCC、Clang、MSVC)都允许这种用法,这也是Stroustrup会把它作为例子的原因。

内容的提问来源于stack exchange,提问作者Birbal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:57:43