Ordering of introduced functions ahead of replicated overridden functions from non-primary

michaelw at ca.ibm.com michaelw at ca.ibm.com
Fri Sep 13 20:41:17 UTC 2002


GCC 3.2 has changed the order of virtual functions. It seems to exhibit an
incorrect behaviour from the ABI in this matter, while gcc 3.0.3 seems to
be correct. Here is an example testcase with all covariant return functions
removed to remove their effects:

class A {
virtual void f();
//virtual A* i();
virtual void j();
int a;
};
class B  {
virtual void f();
virtual void g();
//virtual B* l();
virtual void k();
int b;
};
class C : public A, virtual public B{
virtual void f(); //OR from primary (1)
virtual void g(); // OR of fn introduced by a non-primary base (3)
virtual void h(); //introduced (2)
//virtual C* l(); // covariant OR of fns introduced in non-primary (4)
//virtual C* i(); // covariant OR of fns introduced in primary (2)
int b;
};
C dummyObjectOf_C;
main(){}

Left side is 3.0.3, right side (scrolll over to the right end) is 3.2.
There are 3 differnces:
1. the round brackets beside function names
2. negative offsets are now displayed as their unsigned equivalents
2. the order of function in 3.0.3 is:
f,j,h,g while the order in 3.2 is f,j,g,h
But the ABI Section 2.5.2 cat 2 (non-virtual bases only which also applies
to sharing in mixed bases)
and Cat 3 (virtual bases only which also applies to non-sharing bases)
clearly shows that:

introduced function (h) is preferred over overriden replicated entries (g)

Here is the relevant section of the vtable with change bars:

Vtable for C                                                       Vtable
for C
C::_ZTV1C: 15 entries                                    C::_ZTV1C: 15
entries
0     12                                                                  0
12
4     0
4     0
8     &_ZTI1C                                                     8
&_ZTI1C
12    C::f                                                            |  12
C::f()
16    A::j                                                            |  16
A::j()
20    C::h                                                           |  20
C::g()   <-- g is replicated
24    C::g                                                           |  24
C::h()   <-- h is introduced
28    0
28    0
32    -12                                                            |  32
4294967284
36    -12                                                            |  36
4294967284
40    -12                                                            |  40
4294967284
44    &_ZTI1C                                                      44
&_ZTI1C
48    C::_ZTv0_n12_N1C1fEv                   |  48    C::_ZTv0_n12_N1C1fEv
()
52    C::_ZTv0_n16_N1C1gEv                 |  52    C::_ZTv0_n16_N1C1gEv()
56    B::k                                                          |  56
B::k()

I don't care so much about change #1 (although it does cause us headaches,
but I understand there is no  guarantees to maintain format), but change #2
looks like an unintended side-effect while change #3 , if you agree it
differs from the ABI looks like a serious binary compatibility problem.

Comment?

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