[omniORB] MSVC 6.0 bug with inheritance across namespaces (mo dules)

Dietmar May dcmay@object-workshops.com
Sat, 1 Aug 1998 21:41:11 -0700


Sorry, Irfan, I did not document the problem properly. There IS a bug in
MSVC; you are also correct that duplication of func() in B is illegal.

I was working backwards from the generated C++ when documenting the
problem. In the C++ code, of course, func() is a virtual function in the
base class, and as such, can be overriden in the derived class. My
documentation incorrectly shows func() in B, when it should only be in
A. In fact, X::B was only included in the example to demonstrate that in
the case of inheritance within the same namespace, everything works
fine. The extra (perhaps unnecessary) detail apparently just confused
things.

> > module X
> > {
> >     interface A
> >     {
> >         void func ();
> >     };
> >     interface B : A
> >     {
> >         void func ();
> >     };
> > }
> 
> I am not sure why you are trying to define func() in interface B.  It
> is already there because of interface A.  In addition, I believe this
> is illegal in IDL.

The key here is the following scenario:

module X
{
   interface A
   {
       void func ();
   };
}

module Y
{
   interface B
   {
      void func2 (); //only shown for dispatch sample, below
   };
}

The IDL compiler generates:

namespace X
{
virtual retcode A::dispatch (...)
{
   if(strcmp(fname, "func") == 0)
      func();
}
}

namespace Y
{
virtual retcode A::dispatch (...)
{
   if(strcmp(fname, "func2") == 0)
      func2();
   else
      X::A::dispatch(...);
}
}

However, due to a separate bug in MSVC, X::dispatch() is not properly
handled, and generates an (invalid and incorrect) compiler error.
omniORB handles this using a typedef:

typedef X::A X_A;

Therefore:

namespace Y
{
virtual retcode Y::dispatch (...)
{
   if(strcmp(fname, "func2") == 0)
      func2();
   else
      X_A::dispatch(...);  //note the use of typedef - not X::A::
}
}

However, the MSVC compiler is creating object code as if the
IDL-generated code were (but is NOT):

virtual retcode Y::dispatch (...)
{
   if(strcmp(fname, "func2") == 0)
      func2();
   else
      Y::A::dispatch(...); //oops, references current namespace
}

This is where the x86 assembly code comes in, to demonstrate that this
is what the compiler is actually creating. When running this code, of
course, since it is recursive, it eventually exhausts the stack and
throws a runtime exception.

Thanks for pointing out my documentation error, so it could be
corrected. Hope this clarifies the actual problem.

Dietmar