非void*指针与整数之间的类型转换安全性探讨
关于
intptr_t与对象指针T*的转换安全性问题 直接在intptr_t和任意对象类型指针T*之间双向转换不能保证安全,必须通过void*作为中间转换步骤,原因如下:
- 标准仅明确了两组有安全保证的转换:
- 支持
intptr_t的实现中,void*与intptr_t(或uintptr_t)双向转换后值保持不变; - 任意对象指针
T*与void*双向转换后值保持不变。
- 支持
- 但标准并没有要求
void*的宽度必须大于等于所有对象指针类型的宽度,也没有直接规定T*与intptr_t之间的转换行为。极端情况下,如果某个平台上T*的宽度比void*大,那么仅能容纳void*的intptr_t就无法完整存储T*的信息,直接转换会导致数据丢失,往返转换后原指针值无法恢复。
正确的转换流程示例
#include <cstdint> // T* 转 intptr_t T* ptr = new T(); void* void_ptr = ptr; intptr_t int_ptr = reinterpret_cast<intptr_t>(void_ptr); // intptr_t 转 T* void* restored_void_ptr = reinterpret_cast<void*>(int_ptr); T* restored_ptr = static_cast<T*>(restored_void_ptr);
不推荐的直接转换(无标准保证)
// 不保证安全,不推荐 T* ptr = new T(); intptr_t int_ptr = reinterpret_cast<intptr_t>(ptr); T* restored_ptr = reinterpret_cast<T*>(int_ptr);
内容的提问来源于stack exchange,提问作者ByteEater
相关产品推荐
相关产品推荐

