c++ - Ist es möglich, einen Zeiger auf ein Unterobjekt über einen Zeiger auf ein anderes, nicht verknüpftes Unterobjekt abzurufen?



pointers language-lawyer (1)

Das ist genau definiert:

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

Das Point Objekt ( p ) und sein x - [basic.compound] sind Zeiger-interkonvertierbar aus [basic.compound] :

Zwei Objekte a und b sind Zeiger-interkonvertierbar, wenn:

  • [...]
  • eines ist ein Standardlayout-Klassenobjekt und das andere ist das erste nicht statische Datenelement dieses Objekts oder, wenn das Objekt keine nicht statischen Datenelemente enthält, ein Basisklassen-Unterobjekt dieses Objekts ([class.mem]). , oder:
  • [...]

Wenn zwei Objekte Zeiger-interkonvertierbar sind, haben sie dieselbe Adresse, und es ist möglich, einen Zeiger über einen reinterpret_cast von einem Zeiger auf den anderen zu erhalten.

Das reinterpret_cast<Point*>(x) ist gültig und endet mit einem Zeiger, der auf p . Daher ist es in Ordnung, es direkt zu ändern. Wie Sie sehen, sind der Standardlayoutteil und der erste nicht statische Datenelementteil von Bedeutung.

Obwohl es nicht so ist, als würden die fraglichen Compiler die zusätzliche Last optimieren, wenn Sie einen Zeiger auf py in übergeben und stattdessen px .

Sehen Sie sich diesen einfachen Code an:

struct Point {
    int x;
    int y;
};

void something(int *);

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

    something(&p.x);

    return p.y;
}

Ich gehe davon aus, dass der Rückgabewert von main so optimiert werden kann, dass er return 2; py something keinen Zugriff auf py , erhält es nur einen Zeiger auf px .

Keiner der großen Compiler optimiert jedoch den Rückgabewert von main auf 2 . Godbolt .

Gibt es etwas in der Norm, das es erlaubt, py zu ändern, wenn wir nur Zugriff auf px gewähren? Wenn ja, hängt dies davon ab, ob Point über ein Standardlayout verfügt?

Was ist, wenn ich something(&p.y); benutze something(&p.y); , und return px; stattdessen?





offsetof