Re: Dynamic cast bug with multiple inheritance

From: Carl Daniel [VC++ MVP] (cpdaniel_remove_this_and_nospam_at_mvps.org.nospam)
Date: 03/09/04


Date: Mon, 8 Mar 2004 18:17:04 -0800

Your code as posted contains a couple of errors that should make it not
compile - unfortunately, VC7.1 accepts it as-is.

1. std:exception is not guaranteed to be defined if <exception> hasn't been
included.
2. exception is used as an unqualified name, but there's no 'exception'
class in file scope. It should be std::exception, or a using directive
added.

With those fixes, the code compiles and runs correctly when compiled with
the Whidbey alpha compiler. Looks like this is a bug that was already
fixed.

-cd

Juan Esteban Bernabó wrote:
> /**
> * This are two test cases to show a probable bug on the VC++
> compiler or rt. *
> * A __non_rtti_object exception is throw when tried to dynamically
> downcast
> * from a base virtual class to a derived class from a method called
> from a
> * base class constructor. The funny thing is that if the concrete
> class has
> * a "long" attribute on its body it shows this behavior if it
> doesn´t the code
> * works clean.
> *
> * This probably is a bug in the compiler or the runtime library but
> I first
> * experienced it in VC++ 6.0 SP5 and installed VC++ .NET to try and
> ocurred the
> * same thing.
> * @author Juan Esteban Bernabó (jbernab@ig.com.br)
> */
>
>
> /**
> * If you have the CPPUNIT framework uncomment this otherwise compile
> this with
> * the HAVE_CPPUNIT macro undefined
> */
> //#define HAVE_CPPUNIT 1
> #undef HAVE_CPPUNIT
>
> #ifdef HAVE_CPPUNIT
> #include <cppunit/extensions/HelperMacros.h>
> #endif
>
> #include <iostream>
>
>
>
> class TestVC
> #ifdef HAVE_CPPUNIT
>> public CppUnit::TestFixture
> #endif
> {
> #ifdef HAVE_CPPUNIT
> CPPUNIT_TEST_SUITE( TestVC );
> CPPUNIT_TEST( testVC1 );
> CPPUNIT_TEST_EXCEPTION( testVC2, bad_typeid );
> CPPUNIT_TEST_SUITE_END();
> #endif
>
> public :
>
>
> /**
> * This is kind of a class hierarchy tree.
> * Reference
> * Object Interface
> * Runnable
> * Thread
> * W X
> **/
>
> class Reference
> {
> virtual void testRe() { };
> };
>
> class Interface : virtual public Reference
> {
> virtual void testI() { };
> };
>
> class Object : virtual public Reference
> {
> virtual void testO() { };
> };
>
> class Runnable : virtual public Interface
> {
> virtual void testR() { };
> };
>
> class Thread : public Object, virtual public Runnable
> {
> public:
> Thread( )
> {
> setReference( this );
> }
>
> void setReference( Reference *that )
> {
> Runnable *r = dynamic_cast<Runnable*>( that );
> }
> };
>
> class W : public Thread
> {
> public:
> W() : Thread( ) { }
> long teste;
> };
>
> class X : public Thread
> {
> public:
> X() : Thread( ) { }
> // With this commented out the bug comes to live
> // long teste;
> };
>
> /**
> * The VC bug manifest when you try to dynamic_cast an object that is
> been
> * constructed and has a long attribute, that's the way I reproduced
> this bug
> * but probably there should be others.
> **/
> void testVC2()
> {
> W w;
> }
>
>
> /**
> * With the X class the problem doensn't happen as it has the "test"
> attibute
> * commented out.
> */
> void testVC1()
> {
> X x;
> }
>
>
> };
>
> /** If you dont have CPPUNIT */
> #ifndef HAVE_CPPUNIT
> extern "C" int main()
> {
> TestVC t;
>
> try
> {
> t.testVC1();
> std::cout << "t.testVC1() = OK" << std::endl;
> } catch( exception &e )
> {
> std::cout << "t.testVC2() = " << e.what() << std::endl;
> }
>
> try
> {
> t.testVC2();
> std::cout << "t.testVC2() = OK" << std::endl;
> } catch( exception &e )
> {
> std::cout << "t.testVC2() = " << e.what() << std::endl;
> }
> return 0;
> }
> #endif
>
> #ifdef HAVE_CPPUNIT
> CPPUNIT_TEST_SUITE_REGISTRATION( TestVC );
> #endif



Relevant Pages

  • Re: How to identify the platform & compiler while compiling?
    ... #ifdef LINUX ... with some extra goop for Solaris threads ... the platform and compiler are "Solaris"; ...
    (comp.lang.c)
  • Re: #if in .rc file
    ... Probably rc compiler doesn't support #if, only #ifdef. ... No - my standard generated files contain things like: ...
    (microsoft.public.vc.mfc)
  • Re: VC++ bug with code optimisation enabled?
    ... #ifdef DLL_EXPORT ... It's possible that you are dealing with a real optimization bug as well - ... information and the complete set of compiler options that were used to ...
    (microsoft.public.dotnet.languages.vc)
  • Re: Need versioning ?
    ... Use {$IFDEF XXX} statements. ... compiler directives in your project options. ...
    (borland.public.delphi.thirdpartytools.general)