是否有可能通过指向另一个未关联的子对象的指针来获取指向一个子对象的指针?



看看这个简单的代码:

struct Point {
int x;
int y;
};
void something(int *);
int main() {
Point p{1, 2};
something(&p.x);
return p.y;
}

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

但是,没有一个主要的编译器优化main的返回值2。戈德博尔特。

标准中是否有某些内容允许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]:

在以下情况下,两个对象ab指针可相互转换的:

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

如果两个对象是指针可互转换的,则它们具有相同的地址,并且可以通过reinterpret_­cast从指向另一个对象的指针获取指向一个对象的指针。

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


虽然它不像有问题的编译器,但如果您传递指向p.y的指针并返回p.x,则会优化额外的负载。

相关内容

  • 没有找到相关文章

最新更新