Re[2]: empty base optimization и множественное наследование
От: Faust Россия  
Дата: 30.08.09 06:49
Оценка:
Здравствуйте, Николай Ивченков, Вы писали:

НИ>Возможно, это какие-то неформальные правила Я как-то пытался найти ответ на схожий вопрос: из какого нормативного текста стандарта следует, что два подобъекта, имеющие один и тот же тип и принадлежащие одному и тому же most derived объекту, должны располагаться по разным адресам. Мои поиски так и не увенчались успехом.


НИ>
#include <iostream>

НИ>struct B
НИ>{
НИ>    B *ptr() { return this; }
НИ>};
НИ>struct D : B
НИ>{
НИ>    B b;
НИ>};

НИ>int main()
НИ>{
НИ>    D d;
НИ>    std::cout << (d.ptr() == d.b.ptr()) << std::endl; 
НИ>}

НИ>Может ли равенство d.ptr() == d.b.ptr() быть истинным? Согласно примечанию в 10/5, не может, но примечания не являются нормативными, и разработчики компиляторов вправе их игнорировать. В данном случае VC++ 8.0 и Intel C++ 11.0 располагают data member и базовый подобъект по одному адресу.
спасибо за ответ! но мне кажется, в Вашем случае все объяснимо:
struct B
{
    B *ptr() { return this; }
};
struct D : B    // здесь компилятор реализует EBO
{
    B b;    // адрес b совпадает с адресом наследуемого B
};
// sizeof(D) == 1, и Derived.ptr() == Derived.b.ptr()

struct B
{
    B *ptr() { return this; }
};
struct D : B    // здесь компилятор реализует EBO
{
    B b;    // адрес b совпадает с адресом наследуемого B
    char m_c;
};
// sizeof(D) == 2, и Derived.ptr() == Derived.b.ptr()

struct B
{
    B *ptr() { return this; }
};
struct D : B    // здесь компилятор реализует EBO
{
    char m_c;
    B b;    // адрес b не совпадает с адресом наследуемого B
};
// sizeof(D) == 2, и Derived.ptr() != Derived.b.ptr()
вот что у меня получилось в процессе тестирования:
#include <iostream>

struct base_0
{
    base_0*            ptr_0() { return this; }
};
struct derived_0
    : base_0    // здесь компилятор реализует EBO
{
    base_0            m_base;
};
struct base_1
{
    base_1*            ptr_1() { return this; }
};
struct derived_1
    : base_0    // здесь компилятор реализует EBO
    , base_1    // здесь нет! что ему мешает?  :xz: 
{
    char            m_c;
};

int                    _tmain(int argc, _TCHAR* argv[])
{
    derived_0        Derived0;
    std::cout << "sizeof(base_0) = " << sizeof(base_0) << std::endl;
    std::cout << "sizeof(derived_0) = " << sizeof(derived_0) << std::endl;
    std::cout << "&Derived0 = " << &Derived0 << std::endl;
    std::cout << "Derived0.ptr_0() = " << Derived0.ptr_0() << std::endl;
    std::cout << "Derived0.m_base.ptr_0() = " << Derived0.m_base.ptr_0() << std::endl;
    std::cout << "(Derived0.ptr_0() == Derived0.m_base.ptr_0()) == ";
    std::cout << (Derived0.ptr_0() == Derived0.m_base.ptr_0()) << std::endl << std::endl;
    //std::cout << sizeof(base) << sizeof(derived) << (Derived.ptr() == Derived.m_base.ptr()) << std::endl;
    derived_1        Derived1;
    std::cout << "sizeof(base_0) = " << sizeof(base_0) << std::endl;
    std::cout << "sizeof(base_1) = " << sizeof(base_1) << std::endl;
    std::cout << "sizeof(derived_1) = " << sizeof(derived_1) << std::endl;
    std::cout << "&Derived1 = " << &Derived1 << std::endl;
    std::cout << "Derived1.ptr_0() = " << Derived1.ptr_0() << std::endl;
    std::cout << "Derived1.ptr_1() = " << Derived1.ptr_1() << std::endl;
    std::cout << "(Derived1.ptr_0() == Derived1.ptr_1()) == ";
    std::cout << ((void*)Derived1.ptr_0() == (void*)Derived1.ptr_1()) << std::endl;

    return 0;
}

sizeof(base_0) = 1
sizeof(derived_0) = 1
&Derived0 = 0012FF33
Derived0.ptr_0() = 0012FF33
Derived0.m_base.ptr_0() = 0012FF33
(Derived0.ptr_0() == Derived0.m_base.ptr_0()) == 1

sizeof(base_0) = 1
sizeof(base_1) = 1
sizeof(derived_1) = 2
&Derived1 = 0012FF24
Derived1.ptr_0() = 0012FF24
Derived1.ptr_1() = 0012FF25
(Derived1.ptr_0() == Derived1.ptr_1()) == 0
Мой компьютер прогоняет бесконечный цикл за 9 секунд, но, мне кажется, он мог бы сделать это быстрее...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.