I was debugging some legacy code and while doing that found some inconsistency in the address of this pointer in the class hierarchy like this:
#include <cstdio>
#include <vector>
class ROOT1 {
public:
ROOT1() {}
void printsomething() { printf("ROOT1::printsomething %p\n", this); }
virtual ~ROOT1() {}
};
class SUBROOT : public ROOT1 {
public:
SUBROOT() {}
void printsomething() { printf("SUBROOT::printsomething %p\n", this); }
virtual ~SUBROOT() {}
};
class ROOT2 {
public:
ROOT2() {}
virtual ~ROOT2() {}
void printsomething() { printf("ROOT2::printsomething %p\n", this); }
};
class CHILD : public ROOT2, public SUBROOT {
public:
CHILD() {}
virtual ~CHILD() {}
void printsomething() { printf("CHILD::printsomething %p\n", this); }
};
class GRANDCHILD : public CHILD {
public:
GRANDCHILD() {}
virtual ~GRANDCHILD() {}
void printsomething() { printf("GRANDCHILD::printsomething %p\n", this); }
};
int main() {
try {
GRANDCHILD* line = new GRANDCHILD;
ROOT1* root1 = static_cast<ROOT1*>(line);
SUBROOT* subroot = static_cast<SUBROOT*>(line);
CHILD* child = static_cast<CHILD*>(line);
ROOT2* root2 = static_cast<ROOT2*>(line);
root2->printsomething();
root1->printsomething();
subroot->printsomething();
child->printsomething();
line->printsomething();
} catch (const char* s) {
printf("Throw %s, %d\n", s, sizeof(std::vector<void*>));
}
}
The output I am getting is:
ROOT2::printsomething 0x23cf2b0
ROOT1::printsomething 0x23cf2b8
SUBROOT::printsomething 0x23cf2b8
CHILD::printsomething 0x23cf2b0
GRANDCHILD::printsomething 0x23cf2b0
There is a difference between the addresses of 'this' pointer. If I just swap the order of inheritance, the addresses changes along the class hierarchy. i.e.
class CHILD : public SUBROOT, public ROOT2
Output:
ROOT2::printsomething 0xc9b2b8
ROOT1::printsomething 0xc9b2b0
SUBROOT::printsomething 0xc9b2b0
CHILD::printsomething 0xc9b2b0
GRANDCHILD::printsomething 0xc9b2b0
What could be the reason?
ROOT2::fromchildwith your code .... technically your compiler would be bugged if it produces that result, but your code also has a typo, so i am not sure who to blaimCHILD.static_castis always OK. Then it's multiple inheritance, isn't it expected that the subobjects on different branchs have different address?CHILD::printsomethingnotROOT2::printsomething, except when i added it myself to show that it still has different addrss, the code above should not produceROOT2::printsomethingexcept if the compiler is bugged or the question is wrong.