Компилятору известно расположение, поэтому он выдаст код, который вычислит адрес подобъекта B
в C
.
Давайте рассмотрим простой пример:
class A { int x; };
class B { int y; };
class C: public A, public B { };
B *get(C &c) {
return &c;
}
В get
компилятор должен вычислить, где B
находится в C
. Вот пример скомпилированного кода ( godbolt ):
get(C&): # @get(C&)
lea rax, [rdi + 4]
ret
Это означает, что компилятор добавит 4 байта к адресу входного аргумента (c
) и вернет это (добавляет 4, потому что sizeof(A)
равно 4, и компилятор решил не добавлять никаких дополнительных заполнителей).
Обратите внимание, что если A
пусто, то вполне вероятно, что адрес B
совпадает с C
. И если A
не является пустым (имеет элементы данных c, не относящиеся к состоянию, или имеет виртуальные функции), то адрес B
, скорее всего, будет отличаться. Но все это детали реализации, зависит от платформы ABI (Application Binary Interface).