在存在歧义的情况下,指针可相互转换的对象之间的转换如何工作?

发布于 2025-01-17 12:42:51 字数 1853 浏览 1 评论 0原文

标准 ([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 一起使用(因为 zz 可以与 zx 进行指针互转换代码>zy,并且 zy 可以与 zyxx 进行指针互换。
因此,我的问题是:以下指针将引用哪个对象?(我使用reinterpret_cast,因为它相当于static_casting到 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_casting 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文