Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > dynamic_cast from base to another parent of derived class

Reply
Thread Tools

dynamic_cast from base to another parent of derived class

 
 
Boris
Guest
Posts: n/a
 
      10-04-2006
Maxim Yegorushkin wrote:
> [...]
>> if (typeid(b) == typeid(level2a) || typeid(b) == typeid(level2b) ||
>> typeid(b) == typeid(level2c))
>> {
>> const level1 *l1 = dynamic_cast<const level1*>(&b);
>> }
>>
>> Class level1 is the parent of all the level2 classes. I have to
>> check for several types but don't need to write the same code then
>> at least for all the level2 classes.

>
> I would redesign my hierarchy so, that dynamic_cast would be enough.


I'm open for any suggestions but don't know if I can simplify it. If you
have a function like this:

base *foo();

which returns a level2 class but you know that level2 classes are grouped
then you try to find their parent classes (level1) if in the current
function you don't need to work with level2 classes (of course there are
other functions which need to; thus I can't get rid of any level).

It's not an option either to change the return type of foo() as there are
quite a lot of functions which all work with base classes. It must be
possible to nest them like in bar(foo()). No matter what foo() returns bar()
must be able to work with. And no matter what function is nested it must
return base* to bar().

> [...]
> This is a title of a frequently asked question. The answer is given
> fow to make it work. If you can follow the first advise, which is
>
> <q>
> For a program which is linked against a shared library, no additional
> precautions are needed
> </q>
>
> then no other action is required.


That's what I have and how I ran into this problem: It's a console program
linked to a shared library.

>> Anyway if I can downcast to the actual type and then back to its
>> parent with the following code (no compilation error, no runtime
>> error) why should a dynamic_cast to the parent l1 not work?
>>
>> if (typeid(b) == typeid(level2))
>> {
>> const level2 *l2 = dynamic_cast<const level2*>(&b);
>> const level1 *l1 = l2;
>> }

>
> You could find more help if you posted simplified complete code that
> reproduces what you are observing.


I had created a small test case but unfortunately it worked. The project I
port is too large - it would take some time to track this down which I don't
have currently.

> It might be that you derive privately from your base (class A : B {}
> . dynamic_cast in this case does not work, reinterpret_cast does work
> if your base class is first in the list of the base classes.


But why does it all work then when I link statically?

Boris


 
Reply With Quote
 
 
 
 
Maxim Yegorushkin
Guest
Posts: n/a
 
      10-05-2006
Boris wrote:

[]

> I had created a small test case but unfortunately it worked. The project I
> port is too large - it would take some time to track this down which I don't
> have currently.


So, it's not a gcc problem, is it?

 
Reply With Quote
 
 
 
 
Fred Zwarts
Guest
Posts: n/a
 
      10-05-2006

"Boris" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)...
> [crossposted to gnu.g++.help]
>
> Boris wrote:
>> Boris wrote:
>>> [...] The code I talk about looks like this:
>>>
>>> if (typeid(b) == typeid(level2))
>>> {
>>> const level1 *l1 = dynamic_cast<const level1*>(&b);
>>> }

>>
>> I changed the code for testing purposes and replaced dynamic_cast with
>> reinterpret_cast - this works.
>>
>> I changed then the code to make it look like this:
>>
>> if (typeid(b) == typeid(level2))
>> {
>> const level2 *l2 = dynamic_cast<const level2*>(&b);
>> const level1 *l1 = l2;
>> }
>>
>> 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.
>
> The code construct as above with dynamic_cast is used in various project
> files. When building and linking the shared library some work, others don't.
> I don't know though on what it depends why some dynamic_casts don't work and
> falsely return 0. Is there anything I can do except replacing all
> dynamic_casts? Any g++ experts with ideas?
>
> Boris


Interesting. A few years ago I had a similar problem on an OpenVMS system.
The dynamic_cast did not work properly in a function that was called from
another function in a shareable image (which is similar to a dynamic library
under Linux). An example was code running in a separate thread. Since the
pthread library was in a shareable image, functions running in another thread
were called from functions in a shareable image.
The OpenVMS engineers brought out a patch for the compiler and the run-time
library quickly.

The similarity of these problems strikes me, as the compiler environments are
from very different teams. Apparently there is something in dynamic_cast
that makes it difficult to work from pre-linked parts of a program.

Fred.Zwarts.
 
Reply With Quote
 
Boris
Guest
Posts: n/a
 
      10-05-2006
Maxim Yegorushkin wrote:
> Boris wrote:
>
> []
>
>> I had created a small test case but unfortunately it worked. The
>> project I port is too large - it would take some time to track this
>> down which I don't have currently.

>
> So, it's not a gcc problem, is it?


Just because a small test case works doesn't mean that the compiler is
bug-free. There must be some side conditions which make the bug appear. And
I don't have the time unfortunately to find the exact conditions under which
the bug can be reproduced. Again I repeat that the same souce code linked
statically works perfectly. Thus it could be a problem with the linker,
too - I don't know.

Boris


 
Reply With Quote
 
Boris
Guest
Posts: n/a
 
      10-05-2006
Fred Zwarts wrote:
> [...]
> Interesting. A few years ago I had a similar problem on an OpenVMS
> system.
> The dynamic_cast did not work properly in a function that was called
> from
> another function in a shareable image (which is similar to a dynamic
> library
> under Linux). An example was code running in a separate thread. Since
> the
> pthread library was in a shareable image, functions running in
> another thread
> were called from functions in a shareable image.
> The OpenVMS engineers brought out a patch for the compiler and the
> run-time
> library quickly.
>
> The similarity of these problems strikes me, as the compiler
> environments are
> from very different teams. Apparently there is something in
> dynamic_cast
> that makes it difficult to work from pre-linked parts of a program.


Could you easily reproduce the problem with a small test program or was it
something where some other conditions had to be met? And did you ever try to
link everything statically just to see if the problem disappeared?

Boris


 
Reply With Quote
 
Maxim Yegorushkin
Guest
Posts: n/a
 
      10-05-2006
Boris wrote:
> Maxim Yegorushkin wrote:
> > Boris wrote:
> >
> > []
> >
> >> I had created a small test case but unfortunately it worked. The
> >> project I port is too large - it would take some time to track this
> >> down which I don't have currently.

> >
> > So, it's not a gcc problem, is it?

>
> Just because a small test case works doesn't mean that the compiler is
> bug-free.


True.

You have to come up with a test case to prove that the compiler is
faulty rather than your code.

 
Reply With Quote
 
iftekhar
Guest
Posts: n/a
 
      10-05-2006
just curious. You never mentioned the linker options. did you use the
-rdynamic option for linking the executable?
I had a similar problem a year back. which was solved by using
-rdynamic, if i can remember properly.

Iftekhar

 
Reply With Quote
 
Fred Zwarts
Guest
Posts: n/a
 
      10-09-2006
"Boris" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)...
> Fred Zwarts wrote:
>> [...]
>> Interesting. A few years ago I had a similar problem on an OpenVMS
>> system.
>> The dynamic_cast did not work properly in a function that was called
>> from
>> another function in a shareable image (which is similar to a dynamic
>> library
>> under Linux). An example was code running in a separate thread. Since
>> the
>> pthread library was in a shareable image, functions running in
>> another thread
>> were called from functions in a shareable image.
>> The OpenVMS engineers brought out a patch for the compiler and the
>> run-time
>> library quickly.
>>
>> The similarity of these problems strikes me, as the compiler
>> environments are
>> from very different teams. Apparently there is something in
>> dynamic_cast
>> that makes it difficult to work from pre-linked parts of a program.

>
> Could you easily reproduce the problem with a small test program or was it
> something where some other conditions had to be met? And did you ever try to
> link everything statically just to see if the problem disappeared?


It could not be reproduced in a small program, because it only occurred in
functions called from the shareable image. So, the test program needed
to use some library functions which in turn called the function in which
dynamic_cast was used, which is not easy to do in a small test program.
I encountered the bug when using the pthreads library, exactly a case where
functions in a program (the start functions of the threads) are called from the
library.
At the time I encountered the bug, it was already known to the OpenVMS
compiler group, so I did not have to prove it with a small program, but they
recognized the case and sent me the patch.
So, the conditions under which the bug was exposed were not determined by me,
but I read them in the patch description. It gave an excellent explanation why
dynamic_cast worked in some cases, but failed in others.

Fred.Zwarts.
 
Reply With Quote
 
Boris
Guest
Posts: n/a
 
      10-10-2006
iftekhar wrote:
> just curious. You never mentioned the linker options. did you use the
> -rdynamic option for linking the executable?
> I had a similar problem a year back. which was solved by using
> -rdynamic, if i can remember properly.


I rebuilt everywhing with the default compiler and linker switches. No -f
options or anything else which might affect compiling and linking. I tried
to build the executable with and without -rdynamic (which I never heard of
before and couldn't find in the local man files either). It all didn't help.
The only thing which works is linking statically (which doesn't help me
really as I need to ship a library).

Boris


 
Reply With Quote
 
F.J.K.
Guest
Posts: n/a
 
      10-10-2006
Boris wrote:
> I had created a small test case but unfortunately it worked. The project I
> port is too large - it would take some time to track this down which I don't
> have currently.


Is the bug present in GCC 4.x?
in mainline?

Is there any reason you can't just do? (Real question, not just
rhetorical

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

>From what I take from the discussion so far, you have assured your code

is semantically correct (See Pete Beckers guru-posting). At this point,
I'd just truy to work around and go on with life.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
If a class Child inherits from Parent, how to implementChild.some_method if Parent.some_method() returns Parent instance ? metal Python 8 10-30-2009 10:31 AM
Casting from base to derived class in base constructor pastbin@gmail.com C++ 2 02-07-2008 02:41 PM
Derived::Derived(const Base&) and Derived& operator=(const Base&) developereo@hotmail.com C++ 1 05-23-2007 01:44 PM
Derived::Derived(const Base&) developereo@hotmail.com C++ 4 05-23-2007 09:32 AM
Derived::Derived(const Base&) and Derived& operator=(const Base&) developereo@hotmail.com C++ 1 05-23-2007 12:07 AM



Advertisments