是否可以通过指向另一个未释放子对象的指针来获得一个子对象的指针? [英] Is it possible to get a pointer to one subobject via a pointer to a different, unreleated subobject?
问题描述
看下面这个简单的代码:
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;
}
我希望主要
的返回值可以优化为 return 2;
,因为某些东西
无法访问 py
,它仅获得指向 px
的指针。
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
.
但是,没有一个主要的编译器将 main
的返回值优化为 2
。 Godbolt 。
But, none of the major compilers optimize the return value of main
to 2
. Godbolt.
标准中是否包含某些内容,如果我们仅允许访问 px $,则允许
某物
修改 py
c $ c>?如果是,这是否取决于 Point
是否具有标准布局?
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?
如果我使用 something(& py);
,然后 return px;
代替?
What if I use something(&p.y);
, and return p.x;
instead?
推荐答案
这是定义明确的:
void something(int *x) {
reinterpret_cast<Point*>(x)->y = 42;
}
Point
对象( p
)及其 x
成员是指针可互转换的,来自 [basic.compound] :
The Point
object (p
) and its x
member are pointer-interconvertible, from [basic.compound]:
两个对象 a 和 b 在以下情况下是 pointer-interconvertible 的指针:
Two objects a and b are pointer-interconvertible if:
- [...]
- 一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则是该对象的任何基类子对象该对象([class.mem]),或:
- [...]
如果有两个对象是指针可相互转换的,则它们具有相同的地址,并且可以通过 reinterpret_cast
从指向另一个的指针获取指向一个的指针。
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
。因此,直接修改它很好。如您所见,标准布局部分和第一个非静态数据成员部分都很重要。
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.
尽管这与有问题的编译器不一样如果您将指针传递给 py
并返回 px
,则可以减少额外的负担。
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.
这篇关于是否可以通过指向另一个未释放子对象的指针来获得一个子对象的指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!