comp.lang.ada
 help / color / mirror / Atom feed
* Exchanging objects between programs with different inheritance hierarchies
       [not found] <3DC93287.2EA290F0@myob.com>
@ 2002-11-13  2:19 ` Steven Deller
  2002-11-13  6:05   ` Jim Rogers
  2002-11-13 17:59   ` Jeffrey Carter
  0 siblings, 2 replies; 11+ messages in thread
From: Steven Deller @ 2002-11-13  2:19 UTC (permalink / raw)


Ada experts,
We are in the process of trying to convert some code to GNAT that worked
on another Ada compiler.   The code transmits tagged type objects
between processes, and uses unchecked conversion at the receiving end to
convert to the destination object type.  The objects are various types
derived from a "base" object with identical inheritance "path", but not
identical inheritance hierarchies.  

Using unchecked_conversion depends on the tags being integral to the
record structures.  On GNAT they are not, so the code fails.

The code is clearly incorrect Ada.  

My question is, what this a reliable, portable way to do that transfer.
The "solution" should only involve reasoning from the Ada RM, not any
detailed knowledge of any compiler, including GNAT.

I believe streams and 'Class'Output and 'Class'Input may be the answer,
but find myself unable to fully understand the RM's "contract" with
regard to writing, and then reading, tagged type objects.

I assume 'Class'Input will correctly work when the same *process*
performed the 'Class'Output.

What about the same *program* running as one *process* doing the
'Class'Output and as another *process* of the same program doing the
'Class'Input? (That is, is an Ada compiler allowed to build tag
information at elaboration time, with possible variations from run to
run?)

What about different programs, but with the identical inheritance
hierarchy for the types in question? (There might be other differing
type hierarchies, but not for the types being transmitted.)

Finally, the 64K question.  What if the inheritance hierarchies differ,
but transmission is limited to types that have the identical inheritance
"path" within the hierarchy?

For a specific example, assume the following hierarchy in program X
   Top ( A (aa,ab), B (ba,bb) )

and the following in program Y
   Top( A (aa,ac), B (bb), C(ca,cb) )

i.e. aa is derived from A and A from Top in both programs, using
identical type names and identical type definitions (from the same
sources, but not necessarily compiled on the same system.)

If X uses Top'Class'Output to write an object of type Top.A.aa and Y
uses Top'Class'Input to read the object, will Y have a valid Top.A.aa in
Y with the same data values as were in X?

If X outputs Top.A.ab, what happens in Y when it tries a 'Class'Input?
(Constraint_Error?, erroneous program with bounded error? something
else?).

One last question, which does not affect this particular effort, but
could affect future work.  What if the inheritance hierarchies are
identical in structure, but not in the particular names used for the
various types and components.  Is there anything in 'Class'Output/Input
that would permit exchanging those structurally-equivalent and
inheritance-equivalent types?

Regards,
Steven Deller




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

* Re: Exchanging objects between programs with different inheritance hierarchies
  2002-11-13  2:19 ` Steven Deller
@ 2002-11-13  6:05   ` Jim Rogers
  2002-11-13 15:54     ` Simon Wright
  2002-11-13 17:59   ` Jeffrey Carter
  1 sibling, 1 reply; 11+ messages in thread
From: Jim Rogers @ 2002-11-13  6:05 UTC (permalink / raw)


Steven Deller wrote:

> My question is, what this a reliable, portable way to do that transfer.
> The "solution" should only involve reasoning from the Ada RM, not any
> detailed knowledge of any compiler, including GNAT.


One problem is that the RM does not specify what a tag is.
One compiler may implement tags as a string while another uses
a numeric value.


> 
> I believe streams and 'Class'Output and 'Class'Input may be the answer,
> but find myself unable to fully understand the RM's "contract" with
> regard to writing, and then reading, tagged type objects.


You will need to provide a common package on both systems.
That package should define the tagged types and also a customization of
the 'Class'Input and 'Class'Output operations. Without a common
package between the systems you do not have common types. Remember that
a type's name includes its package name.


> 
> I assume 'Class'Input will correctly work when the same *process*
> performed the 'Class'Output.
> 
> What about the same *program* running as one *process* doing the
> 'Class'Output and as another *process* of the same program doing the
> 'Class'Input? (That is, is an Ada compiler allowed to build tag
> information at elaboration time, with possible variations from run to
> run?)


This is very simple. There should be no surprises with this arrangement.


> 
> What about different programs, but with the identical inheritance
> hierarchy for the types in question? (There might be other differing
> type hierarchies, but not for the types being transmitted.)
> 
> Finally, the 64K question.  What if the inheritance hierarchies differ,
> but transmission is limited to types that have the identical inheritance
> "path" within the hierarchy?


As long as the types are constructed from common packages you should
have no problems. You cannot read a type for which your program has
no definition. Without a definition the tag cannot be recognized,
and resulting dispatching operations cannot be located and executed.


> 

> One last question, which does not affect this particular effort, but
> could affect future work.  What if the inheritance hierarchies are
> identical in structure, but not in the particular names used for the
> various types and components.  Is there anything in 'Class'Output/Input
> that would permit exchanging those structurally-equivalent and
> inheritance-equivalent types?


You need to share the same packages on both sides of an 'Input / 'Output
stream communication. Types defined in two different packages are not
the same type.

Jim Rogers







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

* Re: Exchanging objects between programs with different inheritance hierarchies
@ 2002-11-13 12:18 Grein, Christoph
  0 siblings, 0 replies; 11+ messages in thread
From: Grein, Christoph @ 2002-11-13 12:18 UTC (permalink / raw)


You should have a look at the attribute 'External_Tag. This might solve your 
problem. But extreme care is needed since there is no check that you don't 
define the same external tag for different types.



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

* Re: Exchanging objects between programs with different inheritance hierarchies
  2002-11-13  6:05   ` Jim Rogers
@ 2002-11-13 15:54     ` Simon Wright
  2002-11-13 17:44       ` tmoran
  0 siblings, 1 reply; 11+ messages in thread
From: Simon Wright @ 2002-11-13 15:54 UTC (permalink / raw)


Jim Rogers <jimmaureenrogers@worldnet.att.net> writes:

> Steven Deller wrote:

> > I believe streams and 'Class'Output and 'Class'Input may be the answer,
> > but find myself unable to fully understand the RM's "contract" with
> > regard to writing, and then reading, tagged type objects.
> 
> You will need to provide a common package on both systems.  That
> package should define the tagged types and also a customization of
> the 'Class'Input and 'Class'Output operations.

You almost never have to override 'Input, 'Output. 'Read and 'Write,
perhaps (eg for access types).



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

* RE: Exchanging objects between programs with different inheritance hierarchies
       [not found] <200211131218.NAA13957@bulgaria.otn.eurocopter.de>
@ 2002-11-13 17:22 ` Steven Deller
  2002-11-13 18:12   ` Robert A Duff
  0 siblings, 1 reply; 11+ messages in thread
From: Steven Deller @ 2002-11-13 17:22 UTC (permalink / raw)


> -----Original Message-----
> From: comp.lang.ada-admin@ada.eu.org
> [mailto:comp.lang.ada-admin@ada.eu.org] On Behalf Of Grein, Christoph
> You should have a look at the attribute 'External_Tag. ...

Christoph,
Thanks.  As I thought about the problem last night without an RM handy,
I wondered if one could rep spec the external tag.  Lo and behold, one
can!!!  Just rep spec the derived types, use 'Class'Output/Input on the
"prime" type and we are cooking :-).  Don't even have to override the
default type outputs as long as the same compiler is used on machines
with the same endian-ness.

Love that Ada.

One other question.  Suppose I have
   type Top is tagged ...  -- our "prime" type
   type X <derived from Top>
   type A_Top is access Top'Class ; -- Only allocated objects are used
   type A_X is access X ;

   Obj : A_Top ;

   X : A_X ;

   Obj := function_returning_A_top ;

   X := A_X ( Obj) ;  -- This is allowed, right?

Does the conversion of an A_Top class access type to a specific A_X
access type have any code associated with it, besides a tag check?
(That is, in general does an Ada compiler have to do anything except
check the tag and copy the "pointer"?)  A specific answer for GNAT would
suffice.

I'm guessing there is nothing except the tag check, since "all" was not
used for defining the access types, but I feel a little like I'm
tiptoeing through land mines here (I'd prefer tulips :-) ).

Oh -- does C++ have anything similar for easy exchange of different
class objects across a single stream (without knowing ahead of time
which object is to be read)?  If not, this is another big win for Ada
:-).

Regards,
Steve



   








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

* Re: Exchanging objects between programs with different inheritance hierarchies
  2002-11-13 15:54     ` Simon Wright
@ 2002-11-13 17:44       ` tmoran
  2002-11-14  6:29         ` Simon Wright
  0 siblings, 1 reply; 11+ messages in thread
From: tmoran @ 2002-11-13 17:44 UTC (permalink / raw)


> You almost never have to override 'Input, 'Output. 'Read and 'Write,
I think it's "almost always" rather than "almost never".  If it's an
object of any complexity, in a program that's more than just quick and
dirty, you probably need to code your own routines to have better
control over just how things are laid out in the stream, and how
fast it runs.



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

* Re: Exchanging objects between programs with different inheritance hierarchies
  2002-11-13  2:19 ` Steven Deller
  2002-11-13  6:05   ` Jim Rogers
@ 2002-11-13 17:59   ` Jeffrey Carter
  2002-11-13 18:23     ` Robert A Duff
  1 sibling, 1 reply; 11+ messages in thread
From: Jeffrey Carter @ 2002-11-13 17:59 UTC (permalink / raw)


Steven Deller wrote:
> Ada experts,
> We are in the process of trying to convert some code to GNAT that worked
> on another Ada compiler.   The code transmits tagged type objects
> between processes, and uses unchecked conversion at the receiving end to
> convert to the destination object type.  The objects are various types
> derived from a "base" object with identical inheritance "path", but not
> identical inheritance hierarchies.  
> 
> Using unchecked_conversion depends on the tags being integral to the
> record structures.  On GNAT they are not, so the code fails.
> 
> The code is clearly incorrect Ada.

Had the code used composition rather than type extension this problem 
would not have arisen.

-- 
Jeff Carter
"Mr. President, we must not allow a mine-shaft gap!"
Dr. Strangelove




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

* Re: Exchanging objects between programs with different inheritance hierarchies
  2002-11-13 17:22 ` Steven Deller
@ 2002-11-13 18:12   ` Robert A Duff
  0 siblings, 0 replies; 11+ messages in thread
From: Robert A Duff @ 2002-11-13 18:12 UTC (permalink / raw)


"Steven Deller" <deller@smsail.com> writes:

>    type Top is tagged ...  -- our "prime" type
>    type X <derived from Top>
>    type A_Top is access Top'Class ; -- Only allocated objects are used
>    type A_X is access X ;
> 
>    Obj : A_Top ;
> 
>    X : A_X ;
> 
>    Obj := function_returning_A_top ;
> 
>    X := A_X ( Obj) ;  -- This is allowed, right?

No, to convert to an access type, it has to be a general access type
("access all", usually).  (I'm ignoring the uninteresting case of
derived access types.)

> Does the conversion of an A_Top class access type to a specific A_X
> access type have any code associated with it, besides a tag check?
> (That is, in general does an Ada compiler have to do anything except
> check the tag and copy the "pointer"?)  A specific answer for GNAT would
> suffice.

I can't think of any reason why a compiler would have to generate any
code other than the Tag check.  An access value is usually represented
as a machine address, and converting a machine address to a machine
address is easy.  ;-)

> I'm guessing there is nothing except the tag check, since "all" was not
> used for defining the access types, but I feel a little like I'm
> tiptoeing through land mines here (I'd prefer tulips :-) ).

I don't understand what you're getting at here.  In most compilers,
"all" has no effect on the representation of access types.

Anyway, even on compilers that do funny things with *some* access types,
I suspect that a whole bunch of "access all" types pointing to various
places in a tagged type hierarchy will all be represented the same
(whether class-wide or not).

- Bob



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

* Re: Exchanging objects between programs with different inheritance hierarchies
  2002-11-13 17:59   ` Jeffrey Carter
@ 2002-11-13 18:23     ` Robert A Duff
  2002-11-13 23:17       ` Steven Deller
  0 siblings, 1 reply; 11+ messages in thread
From: Robert A Duff @ 2002-11-13 18:23 UTC (permalink / raw)


Jeffrey Carter <jrcarter@acm.org> writes:

> Steven Deller wrote:
>...  Using unchecked_conversion depends
> > on the tags being integral to the
> > record structures.  On GNAT they are not, so the code fails.

Is this really true?  I thought all Ada compilers store the tag field as
a field in the record (although not always at the same offset)?  What
is GNAT doing that messes up your unchecked conversions?

Maybe I'm missing your point.

- Bob



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

* RE: Exchanging objects between programs with different inheritance hierarchies
  2002-11-13 18:23     ` Robert A Duff
@ 2002-11-13 23:17       ` Steven Deller
  0 siblings, 0 replies; 11+ messages in thread
From: Steven Deller @ 2002-11-13 23:17 UTC (permalink / raw)


> > Steven Deller wrote:
> >...  Using unchecked_conversion depends
> > > on the tags being integral to the
> > > record structures.  On GNAT they are not, so the code fails.
> 
> Is this really true?  I thought all Ada compilers store the 
> tag field as a field in the record (although not always at 
> the same offset)?  What is GNAT doing that messes up your 
> unchecked conversions?
> 
> Maybe I'm missing your point.
> 
> - Bob

I looked at the generated code.  For the tag comparison it was
generating 3 dereferences for an access type and 2 dereferences for an
object.  It appears the single tag word in the record is actually a
pointer to structure with a pointer to the actual value.  In different
programs, those pointers are to different locations, so just uchecked
converting to the unchecked, saved 32-bit value in the original record
does not work.

For Apex, the tag comparison was a simple value comparison and, since it
seemed to work across programs, apparently that value is not a pointer.

Regards,
Steve




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

* Re: Exchanging objects between programs with different inheritance hierarchies
  2002-11-13 17:44       ` tmoran
@ 2002-11-14  6:29         ` Simon Wright
  0 siblings, 0 replies; 11+ messages in thread
From: Simon Wright @ 2002-11-14  6:29 UTC (permalink / raw)


tmoran@acm.org writes:

> > You almost never have to override 'Input, 'Output. 'Read and 'Write,

> I think it's "almost always" rather than "almost never".  If it's an
> object of any complexity, in a program that's more than just quick
> and dirty, you probably need to code your own routines to have
> better control over just how things are laid out in the stream, and
> how fast it runs.

(The following is "as I understand it")

'Input, 'Output use bounds, discriminants or tags to control exactly
what 'Read, 'Write routines get called. So you _must_ get 'Read,
'Write right.

Of course I agree that you may need control over how bounds,
discriminants or tags are written, in which case you'll need to
specify 'Input, 'Output as well. But it's not a 'must'.



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

end of thread, other threads:[~2002-11-14  6:29 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-11-13 12:18 Exchanging objects between programs with different inheritance hierarchies Grein, Christoph
     [not found] <200211131218.NAA13957@bulgaria.otn.eurocopter.de>
2002-11-13 17:22 ` Steven Deller
2002-11-13 18:12   ` Robert A Duff
     [not found] <3DC93287.2EA290F0@myob.com>
2002-11-13  2:19 ` Steven Deller
2002-11-13  6:05   ` Jim Rogers
2002-11-13 15:54     ` Simon Wright
2002-11-13 17:44       ` tmoran
2002-11-14  6:29         ` Simon Wright
2002-11-13 17:59   ` Jeffrey Carter
2002-11-13 18:23     ` Robert A Duff
2002-11-13 23:17       ` Steven Deller

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