Bug#395837: g++-4.1: dynamic_cast returns different results based on the order of bases
Package:g++-4.1
Version:4.1.1-18
What should dynamic_cast return if we have virtual base class that is
first derived publicly, then privately? The following example shows
that in gcc-4.1 dynamic_cast result depends on the order of
declarations:
/////// cl1.cc //////////////
#include <iostream>
using namespace std;
class A {
public:
virtual ~A() {}
};
class B : public virtual A {};
class C : private virtual A {}; //! derived privately
class T { public: virtual ~T() {}};
class D : public C, public B, public T {};
A* f(T* p) {return dynamic_cast<A*>(p);}
int main() {
D* p = new D;
A* q = p;
cout << f(p) << " " << q << endl;
}
////////// end of cl1.cc /////////
g++ cl1.cc && ./a.out
0x804b008 0x804b008
^^^^^^^^^
dynamic_cast from T* to A* is successfull
Now, derive D first from B then C:
////////////////////// cl2.cc /////////////////
#include <iostream>
using namespace std;
class A {
public:
virtual ~A() {}
};
class B : public virtual A {};
class C : private virtual A {};
class T {
public:
virtual ~T() {}
};
class D : public B, public C, public T {}; //! change order of B and C
A* f(T* p) {return dynamic_cast<A*>(p);}
int main() {
D* p = new D;
A* q = p;
cout << f(p) << " " << q << endl;
}
///////////////// end of cl2.cc /////////////
g++ cl2.cc && ./a.out
0 0x804b008
^^
dynamic_cast from T* to A* failed.
On the other hand paragraph 5.2.7.8 of the C++ standard seems to
indicate that dynamic_cast should succeed (T* is public base; is A
unambiguous? -- yes, is A public base - yes (and no?))
Same results with gcc-snapshot.
Vladimir
g++ -v :
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v
--enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr
--enable-shared --with-system-zlib --libexecdir=/usr/lib
--without-included-gettext --enable-threads=posix --enable-nls
--program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu
--enable-libstdcxx-debug --enable-mpfr --with-tune=i686
--enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.2 20061026 (prerelease) (Debian 4.1.1-18)
Reply to: