help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: dynamic_cast from base to another parent of derived class


From: skaller
Subject: Re: dynamic_cast from base to another parent of derived class
Date: Fri, 20 Oct 2006 03:40:18 +1000
User-agent: Pan/0.14.2.91 (As She Crawled Across the Table (Debian GNU/Linux))

On Wed, 04 Oct 2006 00:41:36 +0300, Boris wrote:


>> This works, too. Is there any other possible explanation than a
>> compiler bug why a dynamic_cast<const level1*> should not work?
> 
> It looks like a problem with g++. The code I was talking about is in a 
> shared library. When I link the executable statically dynamic_cast works. 
> When I use however the shared library dynamic_cast returns 0. Same code but 
> different behavior due to linking.
> 
> There is a section "dynamic_cast, throw, typeid don't work with shared 
> libraries" at http://gcc.gnu.org/faq.html#dso. From what I understand though 
> there is not much you can do? I'm using version 3.4.6 of g++ which is the 
> latest of the 3.4.x series.

Boris, this is a very general problem in C++, coupled with
both compiler, library, and linker problems. It's all about
requirements for uniqueness.

Here is a formula to make it all work reliably,
but first definitions:

A *module* is either a shared library or executable

A type is *critical* if it is shared between modules
and must be unique.

* Do not use inline functions for critical types
  -- this forces the RTTI and vtable to be in 
     a specific object file

* if two libraries A,B share some critical entity X, X must
  be instantiated in a third library D on which
  both A and B depend: they must be linked against D
  at compile time.

If you follow these rules everything will work.

You can relax the first rule if you know what member functions
haul in the vtable/rtti.

Example: you have three libraries A, B, and C which are
loaded as plugins in various combinations, and can be
unloaded too! They communicate by dynamic casting or
exceptions, for a type X.

Make sure there is a library D containing X.
Link A,B,C against D.

If you do this, there will be ONE instance of X in D,
and D will remain loaded whilst any one of A,B,C is
loaded. D may be unloaded and reloaded if A,B,C
are all unloaded, and X may end up with a different
address in that case, but you cannot tell except
by 'cheating' such as saving the address as a void*
in the mainline. If that happens .. well you broke
the second rule, since the mainline actually
depended on X and you didn't link D to it in such
a way the dependence is manifest, which is what
the second rule requires. This is very unlikely
to happen, except with debugging code.


-- 
John Skaller <skaller at users dot sf dot net>
Try Felix, the successor to C++ http://felix.sf.net




reply via email to

[Prev in Thread] Current Thread [Next in Thread]