reinterpret_cast 为空值是否合法* [英] Is it Legal to reinterpret_cast to a void*

查看:41
本文介绍了reinterpret_cast 为空值是否合法*的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查看 https://en.cppreference.com/w/cpp/language/reinterpret_cast 并且我注意到它指定了我们总是可以转换为的合法类型:

I was looking at https://en.cppreference.com/w/cpp/language/reinterpret_cast and I noticed that it specifies the legal types we can always cast to:

  • 字节*
  • char*
  • unsigned char*

但我没有在列表中看到void*.这是疏忽吗?我的用例需要 reinterpret_cast,因为我从 int** 转换到 void*.我最终将从 void* 转换回 int**.

But I did not see void* in the list. Is this an oversight? My use case requires a reinterpret_cast because I'm casting from an int** to a void*. And I will eventually cast from the void* back to an int**.

推荐答案

从指向类型的指针转​​换为指向不同类型的指针总是合法的包括 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.

这篇关于reinterpret_cast 为空值是否合法*的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆