comp.lang.ada
 help / color / mirror / Atom feed
* Seemingly wierd conversion for in out parameter
@ 1998-02-20  0:00 Corey Minyard
  1998-02-23  0:00 ` Albert K. Lee
  0 siblings, 1 reply; 7+ messages in thread
From: Corey Minyard @ 1998-02-20  0:00 UTC (permalink / raw)




I've been playing with some techniques with derived types and I ran
across a rather unusual things.  The following program:

with Text_IO; use Text_IO;
with Ada.Tags; use Ada.Tags;

------------------------------------------------------------------------
procedure Tester is

   type Base is abstract tagged null record;
   type Base_Class is access all Base'Class;

   type Der1 is new Base with null record;
   type Der1_Class is access all Der1'Class;

   type Der2 is new Base with null record;
   type Der2_Class is access all Der2'Class;

   procedure Process (Var : in out Base_Class) is
   begin
      Var := new Der2;
   end Process;

   V1 : Der1_Class := new Der1;
-- This will be a compile error.
--   U1 : Der1_Class := new Der2;

begin

   Put_Line("Base tag = " & Expanded_Name(Base'Tag));
   Put_Line("Der1 tag = " & Expanded_Name(Der1'Tag));
   Put_Line("Der2 tag = " & Expanded_Name(Der2'Tag));

   Put_Line("V1 tag = " &  Expanded_Name(V1'Tag));

   Process(Base_Class(V1));

   Put_Line("V1 tag = " &  Expanded_Name(V1'Tag));

end Tester;
------------------------------------------------------------------------

will compile and produce the following output:

------------------------------------------------------------------------
Base tag = TESTER.BASE
Der1 tag = TESTER.DER1
Der2 tag = TESTER.DER2
V1 tag = TESTER.DER1
V1 tag = TESTER.DER2
------------------------------------------------------------------------

As you can see, the variable V1 should not be able to reference a
tagged type of Der2, but this program does that without any errors
under GNAT (the only compiler I have right now).  I would think that
the compiler wouldn't allow a class conversion passed to an in out
parameter, but it seems to.

I'm certainly no language lawyer, but I would image that doing a cast
would make something not a "variable" any more (RM 6.4.1(5)), thus
this would not be legal.  Is GNAT wrong, or is this legal, or is this
a grey area?

Thanks,

-- 
Corey Minyard               Internet:  minyard@acm.org
  Work: minyard@nortel.ca       UUCP:  minyard@wf-rch.cirr.com




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

* Re: Seemingly wierd conversion for in out parameter
  1998-02-23  0:00 ` Albert K. Lee
@ 1998-02-23  0:00   ` Corey Minyard
  1998-02-25  0:00     ` Nick Roberts
  0 siblings, 1 reply; 7+ messages in thread
From: Corey Minyard @ 1998-02-23  0:00 UTC (permalink / raw)



I'm using 3.11a1, but I really want to know if this is legal Ada95 or
a grey area.  If it is not legal, I'll report a bug to ACT.  If it is
a grey area, I won't use it.  If it is legal, I might use it.  I just
can't tell from the RM.

So again I'll ask...  Is this legal Ada95?

aklee@spam.this.interport.net (Albert K. Lee) writes:

> which version of GNAT were you using?
> 
> 
> On Fri, 20 Feb 1998 06:41:02 GMT, Corey Minyard <minyard@acm.org> wrote:
> >
> >I've been playing with some techniques with derived types and I ran
> >across a rather unusual things.  The following program:
> >
> >with Text_IO; use Text_IO;
> >with Ada.Tags; use Ada.Tags;
> >
> >------------------------------------------------------------------------
> >procedure Tester is
> >
> >   type Base is abstract tagged null record;
> >   type Base_Class is access all Base'Class;
> >
> >   type Der1 is new Base with null record;
> >   type Der1_Class is access all Der1'Class;
> >
> >   type Der2 is new Base with null record;
> >   type Der2_Class is access all Der2'Class;
> >
> >   procedure Process (Var : in out Base_Class) is
> >   begin
> >      Var := new Der2;
> >   end Process;
> >
> >   V1 : Der1_Class := new Der1;
> >-- This will be a compile error.
> >--   U1 : Der1_Class := new Der2;
> >
> >begin
> >
> >   Put_Line("Base tag = " & Expanded_Name(Base'Tag));
> >   Put_Line("Der1 tag = " & Expanded_Name(Der1'Tag));
> >   Put_Line("Der2 tag = " & Expanded_Name(Der2'Tag));
> >
> >   Put_Line("V1 tag = " &  Expanded_Name(V1'Tag));
> >
> >   Process(Base_Class(V1));
> >
> >   Put_Line("V1 tag = " &  Expanded_Name(V1'Tag));
> >
> >end Tester;
> >------------------------------------------------------------------------
> >
> >will compile and produce the following output:
> >
> >------------------------------------------------------------------------
> >Base tag = TESTER.BASE
> >Der1 tag = TESTER.DER1
> >Der2 tag = TESTER.DER2
> >V1 tag = TESTER.DER1
> >V1 tag = TESTER.DER2
> >------------------------------------------------------------------------
> >
> >As you can see, the variable V1 should not be able to reference a
> >tagged type of Der2, but this program does that without any errors
> >under GNAT (the only compiler I have right now).  I would think that
> >the compiler wouldn't allow a class conversion passed to an in out
> >parameter, but it seems to.
> >
> >I'm certainly no language lawyer, but I would image that doing a cast
> >would make something not a "variable" any more (RM 6.4.1(5)), thus
> >this would not be legal.  Is GNAT wrong, or is this legal, or is this
> >a grey area?
> >
> >Thanks,
> >
> >-- 
> >Corey Minyard               Internet:  minyard@acm.org
> >  Work: minyard@nortel.ca       UUCP:  minyard@wf-rch.cirr.com

-- 
Corey Minyard               Internet:  minyard@acm.org
  Work: minyard@nortel.ca       UUCP:  minyard@wf-rch.cirr.com




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

* Re: Seemingly wierd conversion for in out parameter
  1998-02-20  0:00 Seemingly wierd conversion for in out parameter Corey Minyard
@ 1998-02-23  0:00 ` Albert K. Lee
  1998-02-23  0:00   ` Corey Minyard
  0 siblings, 1 reply; 7+ messages in thread
From: Albert K. Lee @ 1998-02-23  0:00 UTC (permalink / raw)



which version of GNAT were you using?


On Fri, 20 Feb 1998 06:41:02 GMT, Corey Minyard <minyard@acm.org> wrote:
>
>I've been playing with some techniques with derived types and I ran
>across a rather unusual things.  The following program:
>
>with Text_IO; use Text_IO;
>with Ada.Tags; use Ada.Tags;
>
>------------------------------------------------------------------------
>procedure Tester is
>
>   type Base is abstract tagged null record;
>   type Base_Class is access all Base'Class;
>
>   type Der1 is new Base with null record;
>   type Der1_Class is access all Der1'Class;
>
>   type Der2 is new Base with null record;
>   type Der2_Class is access all Der2'Class;
>
>   procedure Process (Var : in out Base_Class) is
>   begin
>      Var := new Der2;
>   end Process;
>
>   V1 : Der1_Class := new Der1;
>-- This will be a compile error.
>--   U1 : Der1_Class := new Der2;
>
>begin
>
>   Put_Line("Base tag = " & Expanded_Name(Base'Tag));
>   Put_Line("Der1 tag = " & Expanded_Name(Der1'Tag));
>   Put_Line("Der2 tag = " & Expanded_Name(Der2'Tag));
>
>   Put_Line("V1 tag = " &  Expanded_Name(V1'Tag));
>
>   Process(Base_Class(V1));
>
>   Put_Line("V1 tag = " &  Expanded_Name(V1'Tag));
>
>end Tester;
>------------------------------------------------------------------------
>
>will compile and produce the following output:
>
>------------------------------------------------------------------------
>Base tag = TESTER.BASE
>Der1 tag = TESTER.DER1
>Der2 tag = TESTER.DER2
>V1 tag = TESTER.DER1
>V1 tag = TESTER.DER2
>------------------------------------------------------------------------
>
>As you can see, the variable V1 should not be able to reference a
>tagged type of Der2, but this program does that without any errors
>under GNAT (the only compiler I have right now).  I would think that
>the compiler wouldn't allow a class conversion passed to an in out
>parameter, but it seems to.
>
>I'm certainly no language lawyer, but I would image that doing a cast
>would make something not a "variable" any more (RM 6.4.1(5)), thus
>this would not be legal.  Is GNAT wrong, or is this legal, or is this
>a grey area?
>
>Thanks,
>
>-- 
>Corey Minyard               Internet:  minyard@acm.org
>  Work: minyard@nortel.ca       UUCP:  minyard@wf-rch.cirr.com




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

* Re: Seemingly wierd conversion for in out parameter
  1998-02-23  0:00   ` Corey Minyard
@ 1998-02-25  0:00     ` Nick Roberts
  1998-02-26  0:00       ` Bernd Holzmueller
  0 siblings, 1 reply; 7+ messages in thread
From: Nick Roberts @ 1998-02-25  0:00 UTC (permalink / raw)



--
Corey Minyard asked a question about conversion of tagged types.
--

I'm sure I posted an answer to you on this one a while back! Anyway ...

Your test code, and the output, constitute legal Ada 95. No 'grey area'.

The essence of your confusion (I think ;-) lies in the conversion
Base_Class(V1) as an actual parameter in a call to the procedure Process.
This conversion is legal Ada: as with all converted in-out parameters, the
actual variable (V1 in this case (of type Der1_Class)) is converted (to type
Base_Class in this case) on the way in, and then whatever the formal (Var in
this case) has been set to (a value of type Der2_Class in this case) is
converted again (into type Base_Class in this case) on the way out.

It is important to understand that with tagged types these conversions are
'view conversions': they never change the type of the underlying object,
they only ever change the _apparent_ type of the object. Hence, an object's
tag never ever changes during the execution of a program; it is totally
static.

So, when a Der2 object is created (by the allocator ('new')) in Process,
that type (Der2) is, and forever must remain, the type of that object. It's
tag is, and will forever be, TESTER.DER2. View conversions to Der1 or Base
(or anything else) won't ever change its tag or its (underlying) type. Note
that the rules for conversion between access-to-tagged types follow the
rules for conversion between the tagged types themselves.

Tagged types can always be converted towards the root. If you look at the
code, you will see that V1 gets view-converted to Base_Class on the way into
Process: this is OK, because V1 is of type Der1_Class, whose accessed type
is derived from that of Base_Class (i.e. it accesses Der1, which is derived
from Base, which Base_Class accesses). Then, a value of type Der2_Class is
passed out, which gets view-converted to type Base_Class: this is also OK,
because Der2 is also (indirectly) derived from Base. So the conversion never
violates any Ada rule.

Having been passed out, the (external image of the) tag of the object (of
type Der2) accessed by the value (of type Der2_Class) which was passed out
of Process is printed out. This is "TESTER.DER2", because the type of the
object is Der2.

Hopefully, this makes some sense!


------------ Nick Roberts
---------- Croydon, UK
-------- Nick.Roberts@dial.pipex.com
------ Voicemail & Fax +44 181-405 1124
---- Proprietor, ThoughtWing Software
-- Independent Software Development Consultant

    The oceans teem with myriad fishes:
    The land and air are with creatures rife.
    The world is filled with endless complexity;
    This is the simple truth of life. [NJR]

  *** Ada: The Language for a Complex World ***








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

* Re: Seemingly wierd conversion for in out parameter
  1998-02-25  0:00     ` Nick Roberts
@ 1998-02-26  0:00       ` Bernd Holzmueller
  1998-02-26  0:00         ` Stephen Leake
  0 siblings, 1 reply; 7+ messages in thread
From: Bernd Holzmueller @ 1998-02-26  0:00 UTC (permalink / raw)



Nick Roberts wrote:
> 
> --
> Corey Minyard asked a question about conversion of tagged types.
> --
> 
> I'm sure I posted an answer to you on this one a while back! Anyway ...
> 
> Your test code, and the output, constitute legal Ada 95. No 'grey area'.
>
> ... large portion skipped ...
>
> Tagged types can always be converted towards the root. If you look at the
> code, you will see that V1 gets view-converted to Base_Class on the way into
> Process: this is OK, because V1 is of type Der1_Class, whose accessed type
> is derived from that of Base_Class (i.e. it accesses Der1, which is derived
> from Base, which Base_Class accesses). Then, a value of type Der2_Class is
> passed out, which gets view-converted to type Base_Class: this is also OK,
> because Der2 is also (indirectly) derived from Base. So the conversion never
> violates any Ada rule.

If no Ada rule is violated in the program presented by Corey Minyard, 
they should perhaps be reconsidered as the following, slightly extended
program shows:

with Text_IO; use Text_IO;
with Ada.Tags; use Ada.Tags;

------------------------------------------------------------------------
procedure Tester is

   type Base is abstract tagged null record;
   type Base_Class is access all Base'Class;

   type Der1 is new Base with record X: Integer; end record;
   type Der1_Class is access all Der1'Class;

   type Der2 is new Base with record Y: Float; end record;
   type Der2_Class is access all Der2'Class;

   procedure Process (Var : in out Base_Class) is
   begin
      Var := new Der2'(Y => 3.45);
   end Process;

   V1 : Der1_Class := new Der1;
-- This will be a compile error.
--   U1 : Der1_Class := new Der2;

begin

   Put_Line("Base tag = " & Expanded_Name(Base'Tag));
   Put_Line("Der1 tag = " & Expanded_Name(Der1'Tag));
   Put_Line("Der2 tag = " & Expanded_Name(Der2'Tag));

   Put_Line("V1 tag = " &  Expanded_Name(V1'Tag));

   V1.X := 6;

   Process(Base_Class(V1));

   Put_Line("V1 tag = " &  Expanded_Name(V1'Tag));

   Text_Io.Put_Line("V1.X = " & Integer'IMAGE(V1.X));

end Tester;

This program outputs 

Base tag = TESTER.BASE
Der1 tag = TESTER.DER1
Der2 tag = TESTER.DER2
V1 tag = TESTER.DER1
V1 tag = TESTER.DER2
V1.X =  1079823565

and the last line of the output is a typical output of an uninitialized
variable
which is rather strange for a program that has all objects properly
initialized! 

Bernd

-------------------------------------------------------------------
Bernd Holzmueller, Computer Science Department, Stuttgart University
holzmuel@informatik.uni-stuttgart.de
http://www.informatik.uni-stuttgart.de/ifi/ps/bernd.html
-------------------------------------------------------------------




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

* Re: Seemingly wierd conversion for in out parameter
  1998-02-26  0:00       ` Bernd Holzmueller
@ 1998-02-26  0:00         ` Stephen Leake
  1998-02-26  0:00           ` Robert Dewar
  0 siblings, 1 reply; 7+ messages in thread
From: Stephen Leake @ 1998-02-26  0:00 UTC (permalink / raw)



Bernd Holzmueller wrote:
> If no Ada rule is violated in the program presented by Corey Minyard,
> they should perhaps be reconsidered as the following, slightly extended
> program shows:
> 
> with Text_IO; use Text_IO;
> with Ada.Tags; use Ada.Tags;
> 
> ------------------------------------------------------------------------
> procedure Tester is
> 
>    type Base is abstract tagged null record;
>    type Base_Class is access all Base'Class;
> 
>    type Der1 is new Base with record X: Integer; end record;
>    type Der1_Class is access all Der1'Class;
> 
>    type Der2 is new Base with record Y: Float; end record;
>    type Der2_Class is access all Der2'Class;
> 
>    procedure Process (Var : in out Base_Class) is
>    begin
>       Var := new Der2'(Y => 3.45);
>    end Process;
> 
>    V1 : Der1_Class := new Der1;
> -- This will be a compile error.
> --   U1 : Der1_Class := new Der2;
> 
> begin
> 
>    Put_Line("Base tag = " & Expanded_Name(Base'Tag));
>    Put_Line("Der1 tag = " & Expanded_Name(Der1'Tag));
>    Put_Line("Der2 tag = " & Expanded_Name(Der2'Tag));
> 
>    Put_Line("V1 tag = " &  Expanded_Name(V1'Tag));
> 
>    V1.X := 6;
> 
>    Process(Base_Class(V1));
> 
>    Put_Line("V1 tag = " &  Expanded_Name(V1'Tag));
> 
>    Text_Io.Put_Line("V1.X = " & Integer'IMAGE(V1.X));
> 
> end Tester;
> 
> This program outputs
> 
> Base tag = TESTER.BASE
> Der1 tag = TESTER.DER1
> Der2 tag = TESTER.DER2
> V1 tag = TESTER.DER1
> V1 tag = TESTER.DER2
> V1.X =  1079823565
> 
> and the last line of the output is a typical output of an uninitialized
> variable
> which is rather strange for a program that has all objects properly
> initialized!

Running this with ObjectAda 7.1 on Windows 95, we get Constraint_Error
at the call " Process(Base_Class(V1)); ", which is expected since we are
attempting to store a pointer to Der2 in a variable of type access Der1.
GNAT 3.10p on Windows 95 does not raise Constraint_Error here, so I
suspect it has a bug. What compiler are you using? please submit a bug
report!
 
-- 
- Stephe




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

* Re: Seemingly wierd conversion for in out parameter
  1998-02-26  0:00         ` Stephen Leake
@ 1998-02-26  0:00           ` Robert Dewar
  0 siblings, 0 replies; 7+ messages in thread
From: Robert Dewar @ 1998-02-26  0:00 UTC (permalink / raw)



<<Running this with ObjectAda 7.1 on Windows 95, we get Constraint_Error
at the call " Process(Base_Class(V1)); ", which is expected since we are
attempting to store a pointer to Der2 in a variable of type access Der1.
GNAT 3.10p on Windows 95 does not raise Constraint_Error here, so I
suspect it has a bug. What compiler are you using? please submit a bug
report!
>>

Right, of course a Constraint_Error must be raised. That is clear (the
discussion was about whether or not this program is legal, which it
definitely is!)





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

end of thread, other threads:[~1998-02-26  0:00 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-02-20  0:00 Seemingly wierd conversion for in out parameter Corey Minyard
1998-02-23  0:00 ` Albert K. Lee
1998-02-23  0:00   ` Corey Minyard
1998-02-25  0:00     ` Nick Roberts
1998-02-26  0:00       ` Bernd Holzmueller
1998-02-26  0:00         ` Stephen Leake
1998-02-26  0:00           ` Robert Dewar

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