dynamic_cast from base to another parent of derived class

B

Boris

F.J.K. said:
Is the bug present in GCC 4.x?
in mainline?

I don't know, I didn't try yet. For now I'm happy if I can work around the
bug and finally release the software on Linux.
Is there any reason you can't just do? (Real question, not just
rhetorical :)

#ifdef __GNUC__ && __GNU__<4
#define dynamic_cast static_cast
#endif

Yes, I use something like this now:

#if defined(__GNUC__)
const level1 &l1 = *static_range<const level1*>(&base);
#else
is semantically correct (See Pete Beckers guru-posting). At this

I'm as much sure as you can be with C++ code. ;-) What's 100% for sure
though is that everything works when linked statically.

Boris
 
S

skaller

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.
 
M

Maxim Yegorushkin

skaller said:
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.

What about weak symbols? Do not they exist to solve this very problem
when multiple modules export the same symbol? If a symbol is a weak
symbol in all the modules, which is true for typeinfo objects, all the
references to that symbol are resolved to the first one found by ld.so.
Am I missing something?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top