指针互转换与具有相同地址 [英] Pointer interconvertibility vs having the same address

查看:90
本文介绍了指针互转换与具有相同地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标准N4659的工作草案说:

[基本化合物]
如果两个对象是指针可互换的,则它们具有相同的地址

[basic.compound]
If two objects are pointer-interconvertible, then they have the same address

然后注意

即使数组对象和其第一个元素具有相同的地址,它们也不能指针可相互转换

An array object and its first element are not pointer-interconvertible, even though they have the same address

使数组对象及其第一个元素不可指针可互转换的原理是什么?更一般地,将指针可互换性的概念与具有相同地址的概念区分开的原理是什么?那里不存在矛盾吗?

What is the rationale for making an array object and its first element non-pointer-interconvertible? More generally, what is the rationale for distinguishing the notion of pointer-interconvertibility from the notion of having the same address? Isn't there a contradiction in there somewhere?

在给定这种陈述顺序的情况下,看来

It would appear that given this sequence of statements

int a[10];

void* p1 = static_cast<void*>(&a[0]);
void* p2 = static_cast<void*>(&a);

int* i1 = static_cast<int*>(p1);
int* i2 = static_cast<int*>(p2);

我们有p1 == p2,但是i1定义明确,使用i2会导致UB.

we have p1 == p2, however, i1 is well defined and using i2 would result in UB.

推荐答案

显然存在基于此进行优化的实现.考虑:

There are apparently existing implementations that optimize based on this. Consider:

struct A {
    double x[4];
    int n;
};

void g(double* p);

int f() {
    A a { {}, 42 };
    g(&a.x[1]);
    return a.n; // optimized to return 42;
                // valid only if you can't validly obtain &a.n from &a.x[1]
}

给出p = &a.x[1];g可能会尝试通过reinterpret_cast<A*>(reinterpret_cast<double(*)[4]>(p - 1))->n获得对a.n的访问.如果内部强制转换成功产生了指向a.x的指针,则外部强制转换将产生了指向a的指针,从而赋予了类成员访问定义的行为,从而使优化无效.

Given p = &a.x[1];, g might attempt to obtain access to a.n by reinterpret_cast<A*>(reinterpret_cast<double(*)[4]>(p - 1))->n. If the inner cast successfully yielded a pointer to a.x, then the outer cast will yield a pointer to a, giving the class member access defined behavior and thus outlawing the optimization.

这篇关于指针互转换与具有相同地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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