Incorrect example in abi-examples
michaelw at ca.ibm.com
michaelw at ca.ibm.com
Tue Aug 27 04:26:14 UTC 2002
The CXXABI example section
http://www.codesourcery.com/cxx-abi/abi-examples.html
contain an incorrect sample. On page 3:
/*
Test case for sharing virtual bases.
In Most_Derived, share the vptr with
Interface2 but not Interface3, since
Interface3 is indirectly inherited.
Should get:
(long)(Interface1 *)dd - (long)dd = 0
(long)(Interface2 *)dd - (long)dd = 0
(long)(Interface3 *)dd - (long)dd = 8
(long)(Concrete1 *)dd - (long)dd = 8
*/
struct Interface1 {
virtual void foo();
};
struct Interface2 : virtual Interface1 {
virtual void bar();
};
struct Interface3 : virtual Interface2 {
virtual void baz();
};
struct Concrete1 : virtual Interface3 {
virtual void foo();
int i; // important.
};
struct Most_Derived : virtual Interface1,
virtual Interface2,
virtual Concrete1 {
virtual void bar();
};
void Interface1::foo() { }
void Interface2::bar() { }
void Interface3::baz() { }
void Concrete1::foo() { }
void Most_Derived::bar() { }
extern "C" int printf(const char *,...);
#define EVAL(EXPR) printf( #EXPR " = %d\n", (EXPR) );
main()
{
Most_Derived *dd = new Most_Derived;
EVAL((long)(Interface1 *)dd - (long)dd);
EVAL((long)(Interface2 *)dd - (long)dd);
EVAL((long)(Interface3 *)dd - (long)dd);
EVAL((long)(Concrete1 *)dd - (long)dd);
}
G++ 3.0.3 reveals the order is as follows:
Class Most_Derived
size=12 align=4
Most_Derived (0x300a0200) 0 nearly-empty
vptridx=0 vptr=((&Most_Derived::_ZTV12Most_Derived) + 28)
Interface1 (0x300a0240) 0 nearly-empty virtual canonical
primary-for Most_Derived (0x300a0200)
vptridx=4 vbaseoffset=-16
Interface2 (0x300a0280) 4 nearly-empty virtual non-canonical
lost-primary
Interface1 (0x300a02c0) 0 nearly-empty virtual non-canonical
Concrete1 (0x300a0300) 4 virtual canonical
subvttidx=28 vptridx=12 vbaseoffset=-24 vptr=((&Most_Derived::
_ZTV12Most_D
erived) + 68)
Interface3 (0x300a0340) 4 nearly-empty virtual canonical
primary-for Concrete1 (0x300a0300)
subvttidx=44 vptridx=16 vbaseoffset=-28
Interface2 (0x300a0380) 4 nearly-empty virtual canonical
primary-for Interface3 (0x300a0340) lost-primary
subvttidx=20 vptridx=8 vbaseoffset=-20
Interface1 (0x300a03c0) 0 nearly-empty virtual non-canonical
G++ seems correct based on the following rule.
For a stand-alone class:
Primary(Interface2)=Interface1 by virtual nearly empty
Primary(Interface 3)=Interface2 by virtual nearly empty
Primary (Concrete1)=Interface3 by virtual nearly empty
Primary(Most_Derived)=Interface1 since it is the first virtual nearly empty
primary. Most_Derived cannot take Concrete1 since it is virtually inherited
and is not nearly empty.
So Interface2 loses its primary
Michael Wong
VisualAge C++ Compiler kernel Development
IBM Canada Ltd., C2/KD2/8200/MKM
8200 Warden Avenue
Markham, Ontario L6G 1C7
W:905-413-3283 F:905-413-4839
More information about the cxx-abi-dev
mailing list