comp.lang.ada
 help / color / mirror / Atom feed
From: Maciej Sobczak <see.my.homepage@gmail.com>
Subject: Re: Equivalent of dynamic_cast (downcast) for tagged types
Date: Thu, 27 Jan 2011 14:35:28 -0800 (PST)
Date: 2011-01-27T14:35:28-08:00	[thread overview]
Message-ID: <510d779c-d15b-4fc1-b831-bfc578ecdb4b@z3g2000prz.googlegroups.com> (raw)
In-Reply-To: evoxe8yl0jfw.guw86vvdhuzb.dlg@40tude.net

On Jan 27, 5:18 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:

>    if X in T'Class then
>       Do_Something (T (X));  -- No dispatch
>    end if;
>
> The above is a bad idea, because X might be a descendant of T which has
> overridden Do_Something. So you might be looking for this
>
>    if X'Tag = T'Tag then -- X is of T
>       Do_Something (T (X));  -- No dispatch
>    end if;

Thank you, this makes sense.

> Adjust is not called on limited objects.

Yeah, sure. :-D

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41845

I have submitted this bug report more than one year ago. Looks like
nobody even bothered to check it.

The bug submission states that Adjust is wrongly recognized as
overriding, which it shouldn't be - but now I have hit something more
interesting.
I got an exception from a place where a regular dispatching operation
on some class-wide type was done. After some debugging and analysis
the exception appeared to come from s-finroo.adb:45, from
System.Finalization_Root.Adjust, which just raises Program_Error. Why
the heck this Adjust was called on my Controlled_Limited type is a
mystery, but that was easy to confirm: I have added the Adjust
operation for my type, just as in the bug report, and instrumented it
and voila - this proved that the Adjust was really *called*.

But that was just the beginning. I could live with a dummy
implementation of Adjust for my limited (!) type, but the real problem
was with the dispatching operation that I wanted to call. This
operation is a function that returns some access value - it is
declared to be abstract in the base interface and implemented in my
type. There is nothing between the abstract declaration and my
implemetation, but my implementation is *not* called (again,
instrumented), but somehow the result of the call is null, which leads
to a disaster few lines later. Looks like GNAT generated some dummy
body for the abstract function and called that instead.

So, to summarise: yes, Adjust is randomly called on Controlled_Limited
types and it even dispatches properly (wow!), and no, my own
operations do not dispatch and instead something dummy gives me
equally dummy results.

This happens in GNAT GPL 2010, but not in older compilers.
It is really demotivating to see that object orientation in its basic
form still doesn't work in GNAT.

But in addition to downcasting, there is an alternative solution which
I have discovered later on, although have not yet tested.
The idea is if I know the actual type (T) in the procedure that
accepts base interface, then apparently I'm working with a closed set
of types, which is actually true. So instead of relying on class-wide
types and dispatching in this particular place I will add another
version of the same operation that accepts T and operates on it. A bit
of code duplication, but with a chance to work around this not-so-
funny GNAT bug.

--
Maciej Sobczak * http://www.inspirel.com



  parent reply	other threads:[~2011-01-27 22:35 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-27 15:46 Equivalent of dynamic_cast (downcast) for tagged types Maciej Sobczak
2011-01-27 16:18 ` Dmitry A. Kazakov
2011-01-27 17:10   ` J-P. Rosen
2011-01-27 17:35     ` Dmitry A. Kazakov
2011-01-27 22:49     ` Maciej Sobczak
2011-01-27 17:50   ` Georg Bauhaus
2011-01-27 22:35   ` Maciej Sobczak [this message]
2011-01-28  5:07     ` Yannick Duchêne (Hibou57)
2011-01-28  9:16     ` Dmitry A. Kazakov
2011-01-28 13:11       ` AdaMagica
2011-01-28 14:13         ` Dmitry A. Kazakov
2011-01-28 23:51           ` Randy Brukardt
2011-01-29  0:55             ` Adam Beneschan
2011-01-28 16:44       ` Adam Beneschan
2011-01-28 17:21         ` Dmitry A. Kazakov
2011-01-29  0:12           ` Randy Brukardt
2011-01-29  8:47             ` Dmitry A. Kazakov
2011-01-28 17:33         ` Adam Beneschan
2011-01-28 15:13     ` Maciej Sobczak
2011-01-28 17:47       ` Robert A Duff
2011-01-28 22:04         ` Maciej Sobczak
2011-01-30 20:22           ` Stephen Leake
2011-01-31  9:04             ` AdaCore, user community and communication channels Maciej Sobczak
2011-01-31 10:42               ` Georg Bauhaus
2011-01-27 19:33 ` Equivalent of dynamic_cast (downcast) for tagged types Adam Beneschan
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox