将re * _cast`从T *到T(*)[N]是不确定的行为吗? [英] Is it undefined behavior to `reinterpret_cast` a `T*` to `T(*)[N]`?

查看:66
本文介绍了将re * _cast`从T *到T(*)[N]是不确定的行为吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下情形:

std::array<int, 8> a;
auto p = reinterpret_cast<int(*)[8]>(a.data());
(*p)[0] = 42;

这是未定义的行为吗?我认为是.

  • a.data()返回一个int*,它与int(*)[8]

  • 不同
  • cppreference上的类型别名规则 似乎表明reinterpret_cast无效

  • 作为一名程序员,我知道a.data()指向的内存位置是8 int对象的数组

我缺少使该reinterpret_cast有效的任何规则吗?

解决方案

数组对象及其第一个元素不是指针可互换的 * ,因此reinterpret_cast的结果是一个指针键入指向8 int的数组的指针",其值为指向a[0]的指针" 1 .换句话说,尽管是类型,它实际上并不指向任何数组对象.

然后,代码将数组到指针的转换应用于取消引用此类指针(作为索引表达式(*p)[0]的一部分) 2 所产生的左值.仅当左值实际引用数组对象 3 时,才指定该转换的行为.由于在这种情况下不是左值,因此行为由omiss 4 定义.


* 如果问题是为什么数组对象及其第一个元素不能进行指针可互转换?",则已经被询问:> expr.reinterpret.cast]/7 [conv.ptr] /2 [expr.static.cast]/13 [basic.compound]/4 .

2 请参见 [基本. lval]/6 [expr.sub] [expr.add] .

3 [conv.array] :结果是指向数组的第一个元素的指针."

4 [defns.undefined] :未定义的行为是本文档不对此要求强加的行为",包括当本文档省略了行为的任何明确定义时."

Consider the following scenario:

std::array<int, 8> a;
auto p = reinterpret_cast<int(*)[8]>(a.data());
(*p)[0] = 42;

Is this undefined behavior? I think it is.

  • a.data() returns a int*, which is not the same as int(*)[8]

  • The type aliasing rules on cppreference seem to suggest that the reinterpret_cast is not valid

  • As a programmer, I know that the memory location pointed by a.data() is an array of 8 int objects

Is there any rule I am missing that makes this reinterpret_cast valid?

解决方案

An array object and its first element are not pointer-interconvertible*, so the result of the reinterpret_cast is a pointer of type "pointer to array of 8 int" whose value is "pointer to a[0]"1.In other words, despite the type, it does not actually point to any array object.

The code then applies the array-to-pointer conversion to the lvalue that resulted from dereferencing such a pointer (as a part of the indexing expression (*p)[0])2. That conversion's behavior is only specified when the lvalue actually refers to an array object3. Since the lvalue in this case does not, the behavior is undefined by omission4.


*If the question is "why is an array object and its first element not pointer-interconvertible?", it has already been asked: Pointer interconvertibility vs having the same address.

1See [expr.reinterpret.cast]/7, [conv.ptr]/2, [expr.static.cast]/13 and [basic.compound]/4.

2See [basic.lval]/6, [expr.sub] and [expr.add].

3[conv.array]: "The result is a pointer to the first element of the array."

4[defns.undefined]: undefined behavior is "behavior for which this document imposes no requirements", including "when this document omits any explicit definition of behavior".

这篇关于将re * _cast`从T *到T(*)[N]是不确定的行为吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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