53

看看这个简单的代码:

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但是,没有一个主要编译器优化to的返回值2神箭

如果我们只授予访问权限,标准中是否有允许something修改的内容?如果是,这是否取决于是否有标准布局?p.yp.xPoint

如果我使用something(&p.y);, 而return p.x;不是呢?

4

1 回答 1

54

这是非常明确的:

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

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

如果满足以下条件,两个对象ab指针可互转换的

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

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

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


虽然它不像有问题的编译器那样优化额外的负载,如果你传递一个指向p.yin 并返回p.x而不是。

于 2019-09-17T17:21:00.350 回答