且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

reinterpret_cast 为空值是否合法*

更新时间:2023-11-08 11:00:34

从指向类型的指针转​​换为指向不同类型的指针总是合法的包括 void,所以如果 T 是这是合法的 C++ 类型:

It is always legal to convert from a pointer to a type to a pointer to a different type including void, so if T is a type this is legal C++:

T* x;
void *y = reinterpret_cast<void *>(x);

在现实世界中它从不使用,因为 void * 是一种特殊情况,并且您使用 static_cast 获得相同的值:

In real world it is never used because void * is a special case, and you obtain the same value with static_cast:

void *y = static_cast<void *>(x); // equivalent to previous reinterpret_cast

(实际上上面的转换是隐式的,可以简单地写成 void *y = x; - 感谢 Michael Kenzel 注意到它)

(in fact above conversion is implicit and can be simply written void *y = x; - thank to Michael Kenzel for noticing it)

为了更明确,标准甚至在 C++17 的 n4659 草案中说 8.2.10 Reinterpret cast [expr.reinterpret.cast], §7

To be more explicit the standard even says in draft n4659 for C++17 8.2.10 Reinterpret cast [expr.reinterpret.cast], §7

当一个纯右值 v 为对象指针类型转换为对象指针类型指向cv T的指针",结果为static_cast(static_cast(v)).

When a prvalue v of object pointer type is converted to the object pointer type "pointer to cv T", the result is static_cast<cv T*>(static_cast<cv void*>(v)).

当你提到 byte 和 char 是唯一合法的类型时,只是对那些类型的转换后的指针取消引用是合法的.void 未包含在此处,因为您永远无法取消引用 void *.

When you refer to byte and char being the only legal types, it is just that it is legal to dereference the converted pointer only for those types. void is not included here because you can never dereference a void *.

专门回答你的问题

...我正在从 int** 转换为 void*.我最终会从 void* 转换回 int**.

.. I'm casting from an int** to a void*. And I will eventually cast from the void* back to an int**.

标准保证第一个是标准(读取隐式)转换:

The standard guarantees that first one is a standard (read implicit) conversion:

指向 cv T"类型的纯右值,其中 T 是对象类型,可以转换为指针"类型的纯右值简历无效".指针值 (6.9.2) 不会因此转换而改变.

A prvalue of type "pointer to cv T", where T is an object type, can be converted to a prvalue of type "pointer to cv void". The pointer value (6.9.2) is unchanged by this conversion.

所以这总是合法的:

int **i = ...;
void *v = i;

对于反向转换,标准说(在 static_cast 段落中):

For back casting, standard says (in static_cast paragraph):

指向 cv1 void 的指针"类型的纯右值可以转换为指向 cv2 T 的指针"类型的纯右值,

A prvalue of type "pointer to cv1 void" can be converted to a prvalue of type "pointer to cv2 T",

所以这也是合法的

int **j = static_cast<int **>(v);

并且标准确保j == i.