#include <iostream>
#include <stdio.h>
#include <string>
struct A
{
A( const std:: string & pa) : a( pa) { printf ( "CTR: A address: %p\n " , this ) ; }
std:: string a;
} ;
struct B
{
B( const std:: string & pb) : b( pb) { printf ( "CTR: B address: %p\n " , this ) ; }
std:: string b;
} ;
// assumed data layout:
struct C {
C( ) : a( "astring" ) , b( "bstring" ) { }
// ...
A a;
// ...
B b;
} ;
void approach1( A * pa, B * pb )
{
printf ( "approach1: A address: %p B address: %p\n " , pa, pb) ;
// compute offset:
std:: ptrdiff_t offset = static_cast < char * > ( ( void * ) pb) - static_cast < char * > ( ( void * ) pa) ;
// then in some other function...
// given offset and ptr to b, compute ptr to a:
A * a = static_cast < A* > ( ( void * ) ( static_cast < char * > ( ( void * ) pb) + offset) ) ;
printf ( "approach1: a address: %p \n " , a) ;
std:: cout << "approach1: A->a=" << a- > a << std:: endl ;
}
void approach2( A * pa, B * pb )
{
printf ( "approach2: A address: %p B address: %p\n " , pa, pb) ;
std:: ptrdiff_t offset = reinterpret_cast < char * > ( pb) - reinterpret_cast < char * > ( pa) ;
A * a = reinterpret_cast < A* > ( reinterpret_cast < char * > ( pb) + offset ) ;
printf ( "approach2: a address: %p \n " , a) ;
std:: cout << "approach2: A->a=" << a- > a << std:: endl ;
}
main( )
{
C c;
std:: cout << c.a .a << std:: endl ;
approach1( & c.a , & c.b ) ;
approach2( & c.a , & c.b ) ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZz4KCnN0cnVjdCBBCnsKICAgIEEoY29uc3Qgc3RkOjpzdHJpbmcmIHBhKSA6IGEocGEpIHtwcmludGYoIkNUUjogQSBhZGRyZXNzOiAlcFxuIiwgdGhpcykgO30KICAgIHN0ZDo6c3RyaW5nIGE7Cn07CgpzdHJ1Y3QgQgp7CiAgICBCKGNvbnN0IHN0ZDo6c3RyaW5nJiBwYikgOiBiKHBiKSB7cHJpbnRmKCJDVFI6IEIgYWRkcmVzczogJXBcbiIsIHRoaXMpIDt9CiAgICBzdGQ6OnN0cmluZyBiOwp9OwoKLy8gYXNzdW1lZCBkYXRhIGxheW91dDoKc3RydWN0IEMgewoKICAgIEMoKSA6IGEoImFzdHJpbmciKSwgYigiYnN0cmluZyIpIHt9CiAgLy8gLi4uCiAgQSBhOwogIC8vIC4uLgogIEIgYjsKfTsKCnZvaWQgYXBwcm9hY2gxKCBBICpwYSwgQiAqcGIgKQp7CgogICAgcHJpbnRmKCJhcHByb2FjaDE6IEEgYWRkcmVzczogJXAgQiBhZGRyZXNzOiAlcFxuIiwgcGEsIHBiKTsgCiAgICAvLyBjb21wdXRlIG9mZnNldDoKICAgIHN0ZDo6cHRyZGlmZl90IG9mZnNldCA9IHN0YXRpY19jYXN0PGNoYXIqPigodm9pZCopcGIpIC0gc3RhdGljX2Nhc3Q8Y2hhcio+KCh2b2lkKilwYSk7CiAgICAvLyB0aGVuIGluIHNvbWUgb3RoZXIgZnVuY3Rpb24uLi4KICAgIC8vIGdpdmVuIG9mZnNldCBhbmQgcHRyIHRvIGIsIGNvbXB1dGUgcHRyIHRvIGE6CiAgICBBICphID0gc3RhdGljX2Nhc3Q8QSo+KCAodm9pZCopKHN0YXRpY19jYXN0PGNoYXIqPigodm9pZCopcGIpICsgb2Zmc2V0KSApOwogICAgcHJpbnRmKCJhcHByb2FjaDE6IGEgYWRkcmVzczogJXAgXG4iLCBhKTsgCgogICAgc3RkOjpjb3V0IDw8ICJhcHByb2FjaDE6IEEtPmE9IiA8PCBhLT5hIDw8IHN0ZDo6ZW5kbDsKfQoKCnZvaWQgYXBwcm9hY2gyKCBBICpwYSwgQiAqcGIgKQp7CiAgICBwcmludGYoImFwcHJvYWNoMjogQSBhZGRyZXNzOiAlcCBCIGFkZHJlc3M6ICVwXG4iLCBwYSwgcGIpOyAKCiAgICBzdGQ6OnB0cmRpZmZfdCBvZmZzZXQgPSByZWludGVycHJldF9jYXN0PGNoYXIqPihwYikgLSByZWludGVycHJldF9jYXN0PGNoYXIqPihwYSk7CiAgCiAgICBBICphID0gcmVpbnRlcnByZXRfY2FzdDxBKj4oIHJlaW50ZXJwcmV0X2Nhc3Q8Y2hhcio+KHBiKSArIG9mZnNldCApOwogICAgcHJpbnRmKCJhcHByb2FjaDI6IGEgYWRkcmVzczogJXAgXG4iLCBhKTsgCiAgICBzdGQ6OmNvdXQgPDwgImFwcHJvYWNoMjogQS0+YT0iIDw8IGEtPmEgPDwgc3RkOjplbmRsOwp9CgptYWluKCkKewogIEMgYzsKICBzdGQ6OmNvdXQgPDwgYy5hLmEgPDwgc3RkOjplbmRsOwoKICBhcHByb2FjaDEoJmMuYSwgJmMuYik7CiAgYXBwcm9hY2gyKCZjLmEsICZjLmIpOwp9