comp.lang.ada
 help / color / mirror / Atom feed
* Access to interface conversion problem
@ 2007-03-13 15:25 msimonides
  2007-03-13 16:06 ` Robert A Duff
  2007-03-13 20:56 ` Simon Wright
  0 siblings, 2 replies; 7+ messages in thread
From: msimonides @ 2007-03-13 15:25 UTC (permalink / raw)


I have experienced problems upon using an access to tagged type object
converted to an access to ancestor type - Storage_Error is raised when
calling its operations.

After some investigation I found out that address of object (obtained
like this: Object_Ptr.all'Address) is different after conversion.
Using Unchecked_Deallocation for converting the access value solved
the problem.

The situation is analogous to that in program below:

with System.Address_Image; use System;
with Ada.Text_IO; use Ada.Text_IO;

procedure IFace_Cast_Bug is

   type Root_Type is interface;
   type Root_Access is access all Root_Type'Class;

   type Additional_Operations_Type is interface and Root_Type;
   type Additional_Operations_Access is access all
      Additional_Operations_Type'Class;

   type Root_Implementation_Type is new Root_Type with null record;
   type Root_Implementation_Access is access all
      Root_Implementation_Type'Class;

   type Final_Implementation_Type is new Root_Implementation_Type and
      Additional_Operations_Type with null record;
   type Final_Implementation_Access is access all
      Final_Implementation_Type'Class;


   function To_Additional_Operations (Object_Ptr :
Final_Implementation_Access)
      return Additional_Operations_Access
   is
   begin
      return Additional_Operations_Access (Object_Ptr);
   end To_Additional_Operations;


   Object_Ptr  : constant Final_Implementation_Access :=
      new Final_Implementation_Type;

   Iface_Ptr   : constant Additional_Operations_Access :=
      To_Additional_Operations (Object_Ptr);
begin
   Put      (Address_Image (Object_Ptr.all'Address));
   Put      (" /= ");
   Put_Line (Address_Image (IFace_Ptr.all'Address));
end IFace_Cast_Bug;

The output of this program is two addresses, the first one 4 less than
the second one (in my original program the difference is 12).
Removing the Root_Implementation_Type tagged type from inheritance
hierarchy results in identical addresses.

The question is:
Am I doing something wrong with the conversion? I believe that
upcasting should be perfectly safe and operations defined for the
target type should work on the access (and even incorrect downcast
should raise Constraint_Error instead of a Storage_Error postponed to
the first use).

To me this looks like a compiler bug.

I am using GNAT GPL 3.4.6 on Linux.
--
Marcin Simonides




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to interface conversion problem
  2007-03-13 15:25 Access to interface conversion problem msimonides
@ 2007-03-13 16:06 ` Robert A Duff
  2007-03-13 16:54   ` Adam Beneschan
  2007-03-13 20:56 ` Simon Wright
  1 sibling, 1 reply; 7+ messages in thread
From: Robert A Duff @ 2007-03-13 16:06 UTC (permalink / raw)


msimonides@power.com.pl writes:

> The output of this program is two addresses, the first one 4 less than
> the second one (in my original program the difference is 12).
> Removing the Root_Implementation_Type tagged type from inheritance
> hierarchy results in identical addresses.
>
> The question is:
> Am I doing something wrong with the conversion?

I don't know (I didn't read your code carefully), but it is normal for
access values pointing at the same object to be represented by different
addresses, depending on which interface you are viewing the object as.
This is because C++ works that way, and GNAT mimics the C++ conventions
in order to make interfacing Ada with C++ easier.

C++ has a more powerful form of multiple inheritance than Ada does.
If we didn't care about interfacing, we could implement Ada without
this somewhat-strange offsetting of the addresses.

> To me this looks like a compiler bug.

Could be.

- Bob



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to interface conversion problem
  2007-03-13 16:06 ` Robert A Duff
@ 2007-03-13 16:54   ` Adam Beneschan
  2007-03-13 17:35     ` Robert A Duff
  0 siblings, 1 reply; 7+ messages in thread
From: Adam Beneschan @ 2007-03-13 16:54 UTC (permalink / raw)


On Mar 13, 9:06 am, Robert A Duff <bobd...@shell01.TheWorld.com>
wrote:
> msimoni...@power.com.pl writes:
> > The output of this program is two addresses, the first one 4 less than
> > the second one (in my original program the difference is 12).
> > Removing the Root_Implementation_Type tagged type from inheritance
> > hierarchy results in identical addresses.
>
> > The question is:
> > Am I doing something wrong with the conversion?
>
> I don't know (I didn't read your code carefully), but it is normal for
> access values pointing at the same object to be represented by different
> addresses, depending on which interface you are viewing the object as.
> This is because C++ works that way, and GNAT mimics the C++ conventions
> in order to make interfacing Ada with C++ easier.

I still think 'Address should be the same, though.  The definition of
X'Address for an object X is that it is "the address of the first of
the storage elements allocated to X"; and here, after IFace_Ptr has
been converted from Object_Ptr by a legal type conversion,
IFace_Ptr.all and Object_Ptr.all are the same object, so their
'Address should be the same.  It may be the case that IFace_Ptr and
Object_Ptr are represented as different addresses in memory, and that
if you used an Unchecked_Conversion on the access objects themselves,
you might see different values.  But Marcin's code didn't use
Unchecked_Conversion; the 'Addresses should be the same, and if the
addresses stored in memory are different, the compiler needs to adjust
for this when computing 'Address.

This definitely seems like a compiler bug.

                                  -- Adam





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to interface conversion problem
  2007-03-13 16:54   ` Adam Beneschan
@ 2007-03-13 17:35     ` Robert A Duff
  0 siblings, 0 replies; 7+ messages in thread
From: Robert A Duff @ 2007-03-13 17:35 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> writes:

> I still think 'Address should be the same, though.  The definition of
> X'Address for an object X is that it is "the address of the first of
> the storage elements allocated to X";...

Good point.

- Bob



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to interface conversion problem
  2007-03-13 15:25 Access to interface conversion problem msimonides
  2007-03-13 16:06 ` Robert A Duff
@ 2007-03-13 20:56 ` Simon Wright
  2007-03-13 22:32   ` Adam Beneschan
  1 sibling, 1 reply; 7+ messages in thread
From: Simon Wright @ 2007-03-13 20:56 UTC (permalink / raw)


Judging by the result of compiling with -gnatdg (output intermediate
form) and -gnata (assertions), the compiler seems to be complaining
that Root_Implementation_Type isn't an interface. So I guess it's
confused (which would explain the strange (lack of) error messages).

Is this conversion of access values legal in Ada 95? if so -- live and
learn!



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to interface conversion problem
  2007-03-13 20:56 ` Simon Wright
@ 2007-03-13 22:32   ` Adam Beneschan
  2007-03-14  9:06     ` msimonides
  0 siblings, 1 reply; 7+ messages in thread
From: Adam Beneschan @ 2007-03-13 22:32 UTC (permalink / raw)


On Mar 13, 1:56 pm, Simon Wright <simon.j.wri...@mac.com> wrote:
> Judging by the result of compiling with -gnatdg (output intermediate
> form) and -gnata (assertions), the compiler seems to be complaining
> that Root_Implementation_Type isn't an interface. So I guess it's
> confused (which would explain the strange (lack of) error messages).
>
> Is this conversion of access values legal in Ada 95? if so -- live and
> learn!

No, converting from an access-to-classwide to an access-to-interface-
classwide type is not legal in Ada 95.  Mostly this is because there
ain't no interface types.  :)

There are special rules in Ada dealing with converting T1'Class to
T2'Class where either T1 or T2 is an interface type; see 4.6(23.1).

                               -- Adam






^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Access to interface conversion problem
  2007-03-13 22:32   ` Adam Beneschan
@ 2007-03-14  9:06     ` msimonides
  0 siblings, 0 replies; 7+ messages in thread
From: msimonides @ 2007-03-14  9:06 UTC (permalink / raw)


Thank you all for clarifications.

I have also been told via e-mail that this bug has been fixed in the
current GNAT Pro.
For now I'll just keep using the Unchecked_Conversion as it's the only
workaround I've been able to find.
--
Marcin Simonides




^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-03-14  9:06 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-13 15:25 Access to interface conversion problem msimonides
2007-03-13 16:06 ` Robert A Duff
2007-03-13 16:54   ` Adam Beneschan
2007-03-13 17:35     ` Robert A Duff
2007-03-13 20:56 ` Simon Wright
2007-03-13 22:32   ` Adam Beneschan
2007-03-14  9:06     ` msimonides

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