| #include <stdint.h> | |
| #include <stdio.h> | |
| struct Base { | |
| virtual ~Base() = default; | |
| int base_int = 100; | |
| Base *return_me() { return this; } | |
| }; | |
| struct Base_1 : public VIRTUAL Base { | |
| virtual ~Base_1() = default; | |
| int base_1_arr[10] = {100, 101, 102, 103, 104, 105, 106, 107, 108, 109}; | |
| Base *return_base_1() { return return_me(); } | |
| }; | |
| struct Base_2 : public VIRTUAL Base { | |
| virtual ~Base_2() = default; | |
| int base_2_arr[10] = {200, 201, 202, 203, 204, 205, 206, 207, 208, 209}; | |
| Base *return_base_2() { return return_me(); } | |
| }; | |
| struct Derived : public Base_1, Base_2 { | |
| virtual ~Derived() = default; | |
| int derived_int = 1000; | |
| int method_of_derived() { return 500; } | |
| }; | |
| Base *MakeADerivedReportABase() { return (Base *)((Base_1 *)new Derived()); } | |
| Base *ReportABase(Base *input) { return input; } | |
| int main() { | |
| Derived my_derived; | |
| int call_it = my_derived.method_of_derived(); | |
| Base_1 *base_1_ptr = (Base_1 *)&my_derived; | |
| Base_2 *base_2_ptr = (Base_2 *)&my_derived; | |
| Base *base_through_1 = my_derived.return_base_1(); | |
| Base *base_through_2 = my_derived.return_base_2(); | |
| // Call this to make sure the compiler makes it. | |
| Base *fake_base = MakeADerivedReportABase(); | |
| Base *reported_base = ReportABase(fake_base); | |
| uint64_t base_through_1_addr = (uint64_t)base_through_1; | |
| uint64_t base_through_2_addr = (uint64_t)base_through_2; | |
| int64_t base_offset = base_through_2_addr - base_through_1_addr; | |
| printf("Base offset (should be 0): 0x%llx.\n", base_offset); | |
| uint64_t base_1_addr = (uint64_t)base_1_ptr; | |
| uint64_t base_2_addr = (uint64_t)base_2_ptr; | |
| int64_t offset = base_2_addr - base_1_addr; | |
| // Set a breakpoint here | |
| return my_derived.derived_int + base_1_ptr->base_1_arr[0] + | |
| base_2_ptr->base_2_arr[0] + my_derived.return_base_1()->base_int; | |
| } |