提问者:小点点

是否可以通过指向不同的,不相关的子对象的指针来获得指向一个子对象的指针?


看看这个简单的代码:

struct Point {
    int x;
    int y;
};

void something(int *);

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

    something(&p.x);

    return p.y;
}

我希望main的返回值可以优化为return2;,因为某些东西没有访问p.y的权限,它只能获得一个指向p.x的指针。

但是,没有一个主要的编译器将main的返回值优化为2。 天神。

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

如果我使用某事(&p.y);,而返回p.x;,该怎么办?


共1个答案

匿名用户

这是完全定义好的:

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

point对象(p)及其x成员在[basic.compound]:

两个对象a和b是指针可互换的,如果:

  • [...]
  • 一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则是该对象的任何基类子对象([class.mem]),或者:
  • [...]

如果两个对象是指针可互换的,那么它们具有相同的地址,并且可以通过reinterprecast从指向另一个对象的指针获得指向其中一个对象的指针。

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

尽管这与所讨论的编译器不同,但如果您将指向p.y的指针传入并返回p.x,则会优化掉额外的负载。