reinterpret_cast是否可以将无效的指针值转换为有效的指针值? [英] Could reinterpret_cast turn an invalid pointer value into a valid one?

查看:165
本文介绍了reinterpret_cast是否可以将无效的指针值转换为有效的指针值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个联合:

union A{
  int a;
  struct{
    int b;
    } c;
  };

ca不是布局兼容类型,因此无法通过a读取b的值:

c and a are not layout-compatibles types so it is not possible to read the value of b through a:

A x;
x.c.b=10;
x.a+x.a; //undefined behaviour (UB)

审判1

对于以下情况,我认为自C ++ 17以来,我还得到了未定义的行为:

Trial 1

For the case below I think that since C++17, I also get an undefined behavior:

A x;
x.a=10;
auto p = &x.a; //(1)
x.c.b=12;      //(2)
*p+*p;         //(3) UB

让我们考虑 [basic.type]/3 :

每个指针类型的值都是以下之一:

Every value of pointer type is one of the following:

  • 指向对象或函数的指针(据说该指针指向该对象或函数),或
  • 指向对象([expr.add])末尾的指针,或
  • 该类型的空指针值([conv.ptr]),或
  • 一个无效的指针值.
  • a pointer to an object or function (the pointer is said to point to the object or function), or
  • a pointer past the end of an object ([expr.add]), or
  • the null pointer value ([conv.ptr]) for that type, or
  • an invalid pointer value.

我们将这4个指针值类别称为 pointer value genre .

Let's call this 4 pointer values categories as pointer value genre.

指针的值可以从上述类型转换为另一个类型,但是标准对此并没有明确说明. 如果我错了,请随时纠正我.因此,我假设在(1)处p的值是指向的指针.然后在(2)中,a生命结束,并且p的值成为无效的指针值.因此,在(3)中,我得到了UB,因为我尝试在其生命周期之外访问对象(a)的值.

The value of a pointer may transition from of the above mentioned genre to an other, but the standard is not really explicit about that. Fill free to correct me if I am wrong. So I suppose that at (1) the value of p is a pointer to value. Then in (2) a life ends and the value of p becomes an invalid pointer value. So in (3) I get UB because I try to access the value of an object (a) out of its lifetime.

现在考虑这个奇怪的代码:

Now consider this weird code:

A x;
x.a=10;
auto p = &x.a;                 //(1)
x.c.b=12;                      //(2)
p = reinterpret_cast<int*>(p); //(2')
*p+*p;                         //(3) UB?

reinterpret_cast<int*>(p)是否可以将指针值类型从invalid pointer value更改为pointer to值.

Could the reinterpret_cast<int*>(p) change the pointer value genre from invalid pointer value to a pointer to value.

reinterpret_cast<int*>(p)被定义为与static_cast<int*>(static_cast<void*>(p))等效,因此让我们考虑如何定义static_castvoid*int*的定义,

reinterpret_cast<int*>(p) is defined to be equivalent to static_cast<int*>(static_cast<void*>(p)), so let's consider how is defined the static_cast from void* to int*, [expr.static.cast]/13:

指向cv1 void的指针"类型的prvalue可以转换为指向cv2 T的指针"类型的prvalue,其中T是对象类型,而cv2是与cv相同的限定词,或具有比cv1更高的cv资格.如果原始指针值表示内存中字节的地址 A ,并且 A 不满足T的对齐要求,则未指定结果指针值.否则,如果原始指针值指向对象 a ,并且存在类型为T(忽略cv限定)的对象 b ,该对象为 pointer-interconvertible a ,结果是指向 b 的指针.否则,转换后指针值将保持不变.

A prvalue of type "pointer to cv1 void" can be converted to a prvalue of type "pointer to cv2 T", where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified. Otherwise, if the original pointer value points to an object a, and there is an object b of type T (ignoring cv-qualification) that is pointer-interconvertible with a, the result is a pointer to b. Otherwise, the pointer value is unchanged by the conversion.

因此在我们的例子中,原始指针指向对象a.因此,我想reinterpret_cast将无济于事,因为a不在其生存期内. 我的阅读严格吗?这段代码定义得好吗?

So in our case the original pointer pointed to the object a. So I suppose the reinterpret_cast will not help because a is not within its lifetime. Is my reading to strict? Could this code be well defined?

推荐答案

然后,在(2)中,生命终止,p的值变为无效的指针值.

Then in (2) a life ends and the value of p becomes an invalid pointer value.

不正确.当指针指向具有结束了存储期限.

Incorrect. Pointers only become invalid when they point into memory that has ended its storage duration.

在这种情况下,指针变为指向其生存期之外的对象的指针.它指向的对象不见​​了,但是指针不是规范所指的无效". [basic.life] 花了很多时间来解释你的情况可以并且不能指向超出其生存期的对象的指针.

The pointer in this case becomes a pointer to an object outside of its lifetime. The object it points to is gone, but the pointer is not "invalid" in the way the specification means it. [basic.life] spends quite a bit of time explaining what you can and cannot do to pointers to objects outside of their lifetime.

reinterpret_cast不能将指向其生命周期之外的对象的指针转换为指向其生命周期内的其他对象的指针.

reinterpret_cast cannot turn a pointer to an object outside of its lifetime into a pointer to a different object that is within its lifetime.

这篇关于reinterpret_cast是否可以将无效的指针值转换为有效的指针值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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