We recently upgraded to using Visual Studio 2008 for compiling our MacroView source code on Windows. Previously we had used Visual Studio 2003 so there was a jump over the 2005 compiler version. The same version of IDE is now being used across all of our C, C++ and C# code on Windows. The move went fairly smoothly but one of the porting tasks that I didn’t anticipate was the change in the implementation of dynamic_cast and how it relates to a multiple inheritance hierarchy. A problem occurred where a dynamic_cast failed with a VS2008 compiled executable while it didn’t with the VS2003 compiled version. The inheritance hierarchy of the class in question is shown in the diagram. The diagram is my first use of the C++ class diagram support in VS2008 which is quite nifty. I’m not sure how well it will work with collection relationships in C++, but for quickly creating an inheritance diagram it was very nifty.

OPC Meta Bridge Inheritance

I suppose some developers will recoil in horror at the use of multiple-inheritance, but it has actually worked well and well across multiple platforms. The multiple inheritance of IMetaMessageProcessor, IConversationMessageSink and IHandleEventProcessor are all in aid of supporting the interface concept in C++. Each of these interface “classes” have all abstract methods and absolutely no data. The DebugTool class is a convenience class which provides a series of logging functions to any class inheriting from it. This is the aspect of the inheritance hierarchy that feels a bit “dirty”. This approach was taken to minimize the amount of typing needed in a class to call a logging function. This could have also been achieved through composition and some macros to reduce the typing footprint. Regardless, this is the design that was chosen and it has worked well. Purists be damned :^)

Back to the dynamic_cast issue. Testing the VS2008 compiled application showed a dynamic_cast<OpcMetaBridge *>( processor ) where processor is an IMetaMessageProcessor failing. Cracking open the Annotated C++ Reference Manual lead me to the following statement:

The result of a dynamic_cast(v) is of type T. The type T must be a pointer or a reference to a defined class or void *.
If T is a pointer type and v is a pointer of a type for which T is an accessible base class, the result is a pointer to a unique sub object of that class.

So the dynamic_cast was returning a null pointer because MetaCommsServer inherits from IMetaMessageProcessor with protected inheritance. It worked before because VS2003 and all of the other older Unix C/C++ compilers we’re using weren’t matching the standard. VS2008 improves Microsoft’s compliance with the definition of the C++ language.