c++ pointers language-lawyer c++17 offsetof

c++ - ¿Es posible obtener un puntero a un subobjeto a través de un puntero a un subobjeto diferente y no publicado?



pointers language-lawyer (1)

Esto está perfectamente bien definido:

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

El objeto Point ( p ) y su miembro x son interconvertibles por puntero, de [basic.compound] :

Dos objetos ayb son interconvertibles por puntero si:

  • [...]
  • uno es un objeto de clase de diseño estándar y el otro es el primer miembro de datos no estáticos de ese objeto o, si el objeto no tiene miembros de datos no estáticos, cualquier subobjeto de clase base de ese objeto ([class.mem]) o:
  • [...]

Si dos objetos son interconvertibles por puntero, tienen la misma dirección y es posible obtener un puntero a uno de un puntero a otro a través de un reinterpret_cast .

Ese reinterpret_cast<Point*>(x) es válido y termina con un puntero que apunta a p . Por lo tanto, modificarlo directamente está bien. Como puede ver, la parte de diseño estándar y la primera parte del miembro de datos no estáticos son significativas.

Aunque no es como si los compiladores en cuestión optimizaran la carga adicional si pasa un puntero a py y devuelve px lugar.

Mira este código simple:

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

Espero que el valor de retorno de ese main se pueda optimizar para return 2; , como something no tiene acceso a py , solo obtiene un puntero a px .

Pero ninguno de los principales compiladores optimiza el valor de retorno de main a 2 . Godbolt

¿Hay algo en el estándar que permita que something modifique py si solo damos acceso a px ? En caso afirmativo, ¿depende esto de si Point tiene un diseño estándar?

¿Qué pasa si uso something(&p.y); , y return px; ¿en lugar?