Object layout bug with explicit specialization

Wolfgang Bangerth wolf@gaia.iwr.uni-heidelberg.de
Tue Mar 31 05:22:00 GMT 1998


Hi there,

after some consideration, we decided that this must be a bug in the
compiler: when deriving from explicitely specialized classes, the compiler
computes wrong offsets (relative to #this#) for member variables of the
base classes. The result is that a variable has the right value when
accessed in the scope of the base class, but produces a wrong value when
accessed in the scope of the derived class. The following short program
should make this clear.

Notes:
1/ The problem stems from the fact that FinalClass<1> is derived from the
explicitely specialized class Derived<1>, rather than from the general
Derived<dim> template. The compiler seems to ignore this, however, when
computing the addresses of #local[12]# in FinalClass<1>::FinalClass, since
both addresses equal #this#. It is amazing that the compiler even knows
about #local[12]#, if it does not know about the exact class hierarchy,
since Derived<dim> is not derived from Base[12] and thus has no members
#local1# and #local2#.

This confusion about base classes can better be seen when declaring the
general Derived<dim> class like this:
  template <int dim>
  class Derived : public Base1, public Base2 {};
The output of the program then is correct. It is amazing that the
addresses are still right, if Derived<1> is derived from Base1 and Base2,
while Derived<dim> is derived from Base2 and Base1 (note the order).

2/ The compiler throws an internal compiler error when any of the two base
classes of Derived<1> are declared virtual.

3/ The described error shows up with gcc 2.8.0 and 2.8.1, as well as with
egcs 2.91.6 (98/01/22) and 1.0.2. The program generated with gcc 2.7.2.3
is correct. The problem has also been reported to the gcc folks.

4/ I am surprised to see that this error seems not yet to have been
reported, since explicit specialization of classes is not so uncommon
today. This error is so serious, that it should make all programs produce
invalid results which derive from explicitely specialized classes :-(
Anyway, I'm sure you will find what needs to be changed and my hopes are
high that things will be ok again earlier than the next main gcc
release...


Regards
  Wolfgang



---------------------- Sample output ------------------------------------
Base1::Base1():
    &local1=0xeffff9e0
Base2::Base2():
    &local2=0xeffff9e4
Derived<1>::Derived():
    &local1=0xeffff9e0
    &local2=0xeffff9e4
FinalClass<1>::FinalClass():
    this=0xeffff9e0
    &local1=0xeffff9e0
    &local2=0xeffff9e0

---------------------- Sample code ------------------------------------
#include <iostream.h>

// print the function's name, and addresses of local variables
#define PF     cout << __PRETTY_FUNCTION__ << ":" << endl
#define P1     cout << "    &local1=" << &local1 << endl
#define P2     cout << "    &local2=" << &local2 << endl



class Base1 {
  public:
    Base1 () : local1(0)  { PF; P1; };
    int local1;
};


class Base2 {
  public:
    Base2 () : local2(0) { PF; P2; };
    int local2;
};



template <int dim>
class Derived {};

template <>
class Derived<1> : public Base1, public Base2 {
  public:
    Derived () { PF; P1; P2; };
};



template <int dim>
class FinalClass :  public Derived<dim> {
  public:
    FinalClass () { PF; cout << "    this=" << this << endl; P1; P2; };
};



void main () {
  FinalClass<1> a1;
};



----------------------- Compiler options for egcs 1.0.2 ---------------
wolf@eris$ /usr/local/egcs/egcs-1.0.2/bin/g++ -v test7.cc -o x
Reading specs from
/usr/local/egcs/egcs-1.0.2//lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.27/specs
gcc version egcs-2.90.27 980315 (egcs-1.0.2 release)

/usr/local/egcs/egcs-1.0.2//lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.27/cpp
-lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus
-D__GNUC_MINOR__=90 -Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 -D__sparc__
-D__sun__ -D__unix__ -D__svr4__ -D__SVR4 -D__sparc -D__sun -D__unix
-Asystem(unix) -Asystem(svr4) -D__EXCEPTIONS -D__GCC_NEW_VARARGS__
-Acpu(sparc) -Amachine(sparc) test7.cc /var/tmp/ccaOaRL_.ii
GNU CPP version egcs-2.90.27 980315 (egcs-1.0.2 release) (sparc)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/egcs/egcs-1.0.2/include/g++
 /usr/local/include
 /usr/local/egcs/egcs-1.0.2/sparc-sun-solaris2.6/include

/usr/local/egcs/egcs-1.0.2/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.27/include
 /usr/include
End of search list.

/usr/local/egcs/egcs-1.0.2//lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.27/cc1plus
/var/tmp/ccaOaRL_.ii -quiet -dumpbase test7.cc -version -o
/var/tmp/ccaOaRL_.s
GNU C++ version egcs-2.90.27 980315 (egcs-1.0.2 release)
(sparc-sun-solaris2.6) compiled by GNU C version 2.8.1.
 /usr/ccs/bin/as -V -Qy -s -o /var/tmp/ccaOaRL_1.o /var/tmp/ccaOaRL_.s
/usr/ccs/bin/as: WorkShop Compilers 4.X dev 18 Sep 1996

/usr/local/egcs/egcs-1.0.2//lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.27/ld
-V -Y P,/usr/ccs/lib:/usr/lib -Qy -o x
/usr/local/egcs/egcs-1.0.2//lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.27/crt1.o
/usr/local/egcs/egcs-1.0.2//lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.27/crti.o
/usr/ccs/lib/values-Xa.o
/usr/local/egcs/egcs-1.0.2//lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.27/crtbegin.o
-L/usr/local/egcs/egcs-1.0.2//lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.27
-L/usr/local/egcs/egcs-1.0.2//sparc-sun-solaris2.6/lib -L/usr/ccs/bin
-L/usr/ccs/lib -L/usr/local/egcs/egcs-1.0.2//lib /var/tmp/ccaOaRL_1.o
-lstdc++ -lm -lgcc -lc -lgcc
/usr/local/egcs/egcs-1.0.2//lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.27/crtend.o
/usr/local/egcs/egcs-1.0.2//lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.90.27/crtn.o
ld: Software Generation Utilities - Solaris/ELF (3.0)





More information about the Gcc-bugs mailing list