在存在歧义的情况下,指针可相互转换的对象之间的转换如何工作?
标准 ([expr.static.cast#13])说:
“指向 cv1 void 的指针”类型的纯右值可以转换为“指向 cv2 T 的指针”类型的纯右值。 [...] 如果原始指针值指向对象 a,并且存在可与 a 指针相互转换的 T 类型对象 b(忽略 cv 限定),则结果是指向 b 的指针。 否则,指针值不会因转换而改变。
对我来说,这听起来有点像最多应该有一个这样的对象 b
可以与 a
进行指针互换。但请考虑以下示例:
struct X { };
struct Y { X xx; };
union Z { X x; Y y; };
上述所有类型都是标准布局类 ([class.道具#3])。在以下代码中:
Z z = {};
对象 z
是指针可互转换的 ([basic.compound#4]) 与 zx
一起使用,但也与 zyxx
一起使用(因为 z
与 z
可以与 zx
进行指针互转换代码>zy,并且 zy
可以与 zyxx
进行指针互换。
因此,我的问题是:以下指针将引用哪个对象?(我使用reinterpret_cast
,因为它相当于static_cast
ing到 void*
然后到 X*
)
X* ptr = reinterpret_cast<X*>(&z);
我知道在我的示例中,zy
不在其生命周期内,但我认为它不是没问题,因为cppreference.com 有一个类似的示例,其中一个对象不在其生命周期内:
[...]
union U { int a; double b; } u = {0};
[...]
int* p3 = reinterpret_cast<int*>(&u); // value of p3 is "pointer to u.a": u.a and u are
// pointer-interconvertible
double* p4 = reinterpret_cast<double*>(p3); // value of p4 is "pointer to u.b": u.a and
// u.b are pointer-interconvertible because
// both are pointer-interconvertible with u
The standard ([expr.static.cast#13]) says that:
A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T”. [...]
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.
To me, this sounds a bit like there should always be at most one such object b
that is pointer-interconvertible with a
. But consider the following example:
struct X { };
struct Y { X xx; };
union Z { X x; Y y; };
All of the above types are standard layout classes ([class.prop#3]). In the following code:
Z z = {};
the object z
is pointer-interconvertible ([basic.compound#4]) with z.x
, but also with z.y.xx
(because z
is pointer-interconvertible with z.y
, and z.y
is pointer-interconvertible with z.y.xx
).
Therefore, my question is: which of the objects will the following pointer refer to? (I'm using reinterpret_cast
because it's equivalent to static_cast
ing to void*
and then to X*
)
X* ptr = reinterpret_cast<X*>(&z);
I am aware that in my example, z.y
is not within its lifetime, but I assume that isn't a problem, because cppreference.com has a similar example where one of the objects is not within its lifetime:
[...]
union U { int a; double b; } u = {0};
[...]
int* p3 = reinterpret_cast<int*>(&u); // value of p3 is "pointer to u.a": u.a and u are
// pointer-interconvertible
double* p4 = reinterpret_cast<double*>(p3); // value of p4 is "pointer to u.b": u.a and
// u.b are pointer-interconvertible because
// both are pointer-interconvertible with u
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论