是否有可能通过指向另一个不相关的子对象的指针获得指向一个子对象的指针?

Is it possible to get a pointer to one subobject via a pointer to a different, unreleated subobject?

看看这个简单的代码:

struct Point {
    int x;
    int y;
};

void something(int *);

int main() {
    Point p{1, 2};

    something(&p.x);

    return p.y;
}

我希望 main 的 return 值可以优化为 return 2;,因为 something 无法访问 p.y,它只得到一个指向 p.x.

的指针

但是,none 的主要编译器将 main 的 return 值优化为 2Godbolt.

标准中是否有某些内容允许 something 修改 p.y,如果我们只授予对 p.x 的访问权限?如果是,这是否取决于 Point 是否具有标准布局?

如果我使用 something(&p.y);return p.x; 会怎样?

这是完全明确的:

void something(int *x) {
    reinterpret_cast<Point*>(x)->y = 42;
}

Point 对象 (p) 及其 x 成员是指针可相互转换的,来自 [basic.compound]:

Two objects a and b are pointer-interconvertible if:

  • [...]
  • one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, any base class subobject of that object ([class.mem]), or:
  • [...]

If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_­cast.

reinterpret_cast<Point*>(x) 是有效的,并且以指向 p 的指针结尾。因此,直接修改它是可以的。如您所见,标准布局部分和第一个非静态数据成员部分很重要。


尽管如果您将指向 p.y 的指针传递给 return p.x 而不是问题中的编译器,则不会优化额外的负载。