Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / CodeWarrior / August 2005



Tip: Looking for answers? Try searching our database.

dynamic cast malfunction?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Kurt Bigler - 18 Aug 2005 22:14 GMT
Are there any known problems with dynamic_cast?

It is my understanding that dynamic_cast should be able to cast to a sibling
class, i.e. if you have:

   class A: public B, public C { ... };

then it should be possible to cast an object of actual type A which is
statically typed C where the dynamic_cast occurs, to type B (or to a
superclass of B).

That is, I expect the following to be legit:

   A::Test ()
   {
       Example ();  // call a C member function
   }

   C::Example ()
   {
       B *b = dynamic_cast<B *> (this);

       ...
   }

I am finding that this fails.  Curiously in this case dynamic_cast returns
-1 (0xFFFFFFFF) in most targets, but is returning 0 in my brand-new Mach-O
target.  Is there any reason why dynamic_cast should behave differently in a
Mach-O vs CFM target?

I was neglecting to check for a 0 result from dynamic_cast before
dereferencing the result.  Curiously dereferencing -1 caused no crash
whereas dereferencing 0 does.

I'm seeing this problem in CW 9.6, and most like it was present in earlier
versions.

I need to investigate this more carefully since the above abstracted example
is not actual code I have tested, but is an abstraction for purposes of this
message of code in a large application.  So other possible contributing
factors have not been weeded out, but there is no sign of damaged objects
and the code that reveals the -1 result from dynamic_cast has been running
for years with no crashes.

However I wanted to ask before going too deep in my investigation whether
there are known problems in this area, or whether I've somehow missed
something basic about dynamic_cast.

Thanks in advance for any info.

-Kurt Bigler
Pierre Guyot - 18 Aug 2005 23:08 GMT
> Are there any known problems with dynamic_cast?
>
[quoted text clipped - 43 lines]
> there are known problems in this area, or whether I've somehow missed
> something basic about dynamic_cast.

Bonsoir,

dynamic_cast is supposed to return null when the initial object is not a
base of the target objetc:

class A1 {};

class B : public C {};

{
 B* Some_B = new B() ;

 A1* Some_A1 = dynamic_cast<A1*>(Some_B) ; // Some_A1 will be null
}

It shall be noted that dynamic_cast is not defined before the full
construction of the implied objects. (in fact, at that stage, the
behavior of dynamic_cast is compiler implementation dependent).
This means that using dynamic_cast inside some constructor is tricky:

class A, public B {};

A:A()
{
 C* MyC = this ; // Ok, the base C is defined here
 B* MyB = this ; // Ok, the base B is defined here

 A* MyselfA = dynamic_cast<A*>(MyC) ; // __wrong__ !!!!
 B* MyselfB = dynamic_cast<B*>(MyC) ; // __wrong__ !!!!
   // here, dynamic_cast's behavior is compiler dependent...
   // including for the already constructed base B
 // Don't forget also that calling here a function that uses
 // dynamic_cast will give compiler dependent result...
}

HTH

Signature

Pierre Guyot
pmaguyot @ free . fr

Kurt Bigler - 19 Aug 2005 00:25 GMT
in article
1h1il3e.1ie12sk1xd29csN%pmaguyot@mon.adresse.est.ailleurs.net.invalid,
Pierre Guyot at pmaguyot@mon.adresse.est.ailleurs.net.invalid wrote on
8/18/05 3:08 PM:

>> Are there any known problems with dynamic_cast?
>>
[quoted text clipped - 28 lines]
> dynamic_cast is supposed to return null when the initial object is not a
> base of the target objetc:

I guess I'll have to break down and read the standard on this.  I've
consulted a bunch of sources including a too-vague explanation in
Stroustroup's Design and Evolution of C++, and a bunch of web sources.
There seems to be some agreement that both up- and down-casting are
permitted.  An MSDN article indicates that side-casting is permitted, but
conceivably this pertains to a VC++ extension rather than standard C++.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm
/express_72.asp

I expected that with run-time type information available that dynamic_cast
should succeed whenever the cast was in fact legitimate, i.e. when the
actual type of the object is of the class being cast to or a subclass of
that class.  This assumes no ambiguity is involved, although often there are
tricks for resolving ambiguity by breaking the cast down into several steps,
as the MSDN article suggests.

The issue of -1 rather than 0 being returned remains a CW bug, or else a
failure of the debugger to display the correct value.  I'll test this by
checking for NULL in the code.

-kurt
Kurt Bigler - 19 Aug 2005 03:07 GMT
> Pierre Guyot at pmaguyot@mon.adresse.est.ailleurs.net.invalid wrote on
> 8/18/05 3:08 PM:
[quoted text clipped - 29 lines]
>
> I guess I'll have to break down and read the standard on this.

I haven't *quite* consulted the standard (but see below), but I've confirmed
that in non-Mach-O targets CodeWarrior's dynamic_cast supports the side-ways
casting that I expected.  Behavior of released applications indicate that
this behavior has worked since early 2000.

The debugger's display of 0xFFFFFFFF as the dynamic_cast result in
non-Mach-O targets is apparently a debugger fluke, wherein displayed value
behavior suggests that optimization is turned on when in fact all
optimization is off.  I'll save that issue for a separate thread.

Only in the new Mach-O target is dynamic_cast returning 0 in this case.  So
this is at least an inconsistency in the Mach-O implementation, if not a
violation of the standard.

Regarding the standard, I could not find the C++ standard online just now,
only the 1997 public-review document, but it seems to support my case:

> 5.2.7  Dynamic cast                                [expr.dynamic.cast]
>
[quoted text clipped - 3 lines]
> defined in a dynamic_cast.  The dynamic_cast operator shall  not  cast
> away constness (_expr.const.cast_).

[snip]

> 8 The run-time check logically executes as follows:
>
[quoted text clipped - 11 lines]
>
> --Otherwise, the run-time check fails.

Mapping this onto my example (see quoted material above for full details):

   B *b = dynamic_cast<B *> (this);

T maps to B and v maps to "this".

In my reading it is the 2nd ("Otherwise") paragraph that covers my
situation.  I'll requote that paragraph with my notes added:

> --Otherwise, if v

"this"

> points (refers) to a public base class sub-object of
> the most derived object,

the complete object of class "A"

> and the type of the most derived object

namely A

> has an unambiguous public base class of type T,

in this case T maps to B, so this is satisfied because A has an unambiguous
public base class of type B

> the result is a pointer
> (an lvalue referring) to  the  T  sub-object  of  the  most  derived
> object.

So the result is a pointer to the B sub-object of the A object.

So I tentatively think the Mach-O implementation of dynamic_cast is buggy.
(Can someone confirm that this thinking is correct?)  And in any case it
does not support dynamic_cast behavior that is supported in CFM targets.

Thanks.

-Kurt Bigler
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.