关于误用union将int转换为int*的技术问询(出自《C++ PL》)
Hey, great question—this is exactly the kind of pitfall Bjarne is warning about in The C++ Programming Language. Let's break down why using a union for this sort of "type conversion" is risky, and what you should do instead.
Why union-based type punning is unsafe
First, let's clarify: when people use a union to cast an int to an int*, they're relying on bit equivalence—assuming that the raw bits of the int will map directly to a valid pointer. But this is not a valid conversion, and here's why:
- Size mismatch: On many systems (like 64-bit machines), an
intis 4 bytes, while anint*is 8 bytes. Shoving anintinto a union's pointer member will either truncate the value or leave half the pointer's bytes uninitialized—either way, the result is garbage. - No standard guarantees: C++ doesn't mandate that different types share the same memory layout or alignment rules. Even if
intandint*happened to be the same size on your system, the compiler or hardware could handle their bit patterns in incompatible ways (like endianness differences for multi-byte values). - Undefined behavior: Most importantly, this use of unions falls into the category of undefined behavior. Compilers are free to optimize away this code entirely, or produce results that make no sense—you can't rely on it working consistently across compilers or even different compiler versions.
The correct way to do type conversions (when you really need to)
If you absolutely have to convert between a numeric type and a pointer (and let's be real—this should be a rare edge case, not a regular practice), use C++'s explicit conversion tools:
reinterpret_cast: This is the intended tool for low-level type conversions that bypass type safety. For example:
It's still dangerous, but it's explicit—anyone reading your code will immediately see that you're doing a low-level cast, and the compiler won't treat it as an accidental mistake.int my_int = 0x12345678; int* ptr = reinterpret_cast<int*>(my_int);std::bit_cast(C++20+): If you need to copy the exact bit pattern from one type to another (and both types have the same size), this is the safe, standard-compliant way. It will fail to compile if the types don't match in size, preventing some mistakes:#include <bit> int my_int = 0x12345678; // Only works if sizeof(int) == sizeof(int*) int* ptr = std::bit_cast<int*>(my_int);
A quick note on design
Before reaching for any of these casts, take a step back: do you really need to convert between an integer and a pointer? In most high-level C++ code, this sort of operation is a sign that your design could be improved—try to use type-safe constructs instead of relying on low-level memory hacks.
内容的提问来源于stack exchange,提问作者Birbal

