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

浪尽此生 提交于 2020-06-22 11:05:34

问题


Look at this simple code:

struct Point {
    int x;
    int y;
};

void something(int *);

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

    something(&p.x);

    return p.y;
}

I expect, that main's return value can be optimized to return 2;, as something doesn't have access to p.y, it only gets a pointer to p.x.

But, none of the major compilers optimize the return value of main to 2. Godbolt.

Is there something in the standard, which allows something to modify p.y, if we only give access to p.x? If yes, does this depend on whether Point has standard layout?

What if I use something(&p.y);, and return p.x; instead?


回答1:


This is perfectly well-defined:

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

The Point object (p) and its x member are pointer-interconvertible, from [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.

That reinterpret_cast<Point*>(x) is valid and does end up with a pointer that points to p. Hence, modifying it directly is fine. As you can see, the standard-layout part and the first non-static data member part are significant.


Although it's not like the compilers in question optimize out the extra load if you pass a pointer to p.y in and return p.x instead.



来源:https://stackoverflow.com/questions/57979009/is-it-possible-to-get-a-pointer-to-one-subobject-via-a-pointer-to-a-different-u

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!