How the compiler determines the location of an element when accessed through a base pointer

It just jumped into my head and I can't figure it out.

If I have a code like this:

struct A { char x[100]; };

struct B { int data; };

struct C : A, B {};

#include <iostream>
using namespace std;

B* get_me_some_stuff()
{
        static int x = 0;
        if (++x % 2 == 0)
                return new B();
        else
                return new C();
}

int main()
{
        B* x = get_me_some_stuff();
        B* y = get_me_some_stuff();

        x->data = 10;
        y->data = 20;

        cout << x->data << " " << y->data << endl;

        return 0;
}

How does the compiler determine the location of member memory data?

+5
source share
2 answers

Try the following:

C* x = new C();
B* y = x;
cout << x << " " << y << endl;

Output for me:

0x1ae2010 0x1ae2074

The cast act from C*to B*(or in another direction) includes the necessary arithmetic of the pointer.

+2
source

Your x and y pointers actually point to subobject B of objects B and C (using the most derived type).

Example:

int main() {
  C c;
  B *pb = &c; // converting the pointer here actually adjusts the address

  void *pvc = &c; // doesn't adjust, merely type conversion
  void *pvb = pb; // doesn't adjust, merely type conversion

  cout << boolalpha;
  cout << (pvc == pvb) << '\n'; // prints false
  cout << (&c == pb) << '\n'; // prints true!
                              // (&c is converted to a B* for the comparison)

  C *pc = static_cast<C*>(pb); // this static_cast, which is UB if pb doesn't
    // actually point to a C object, also adjusts the address

  cout << (pc == &c) << '\n'; // prints true

  return 0;
}

? static_cast void * ( reinterpret_cast), void , void:

reinterpret_cast<C*>(pvb)  // undefined behavior
+4

All Articles