Здравствуйте, Николай Ивченков, Вы писали:
НИ>Возможно, это какие-то неформальные правила
Я как-то пытался найти ответ на схожий вопрос: из какого нормативного текста стандарта следует, что два подобъекта, имеющие один и тот же тип и принадлежащие одному и тому же 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 секунд, но, мне кажется, он мог бы сделать это быстрее...