comp.lang.ada
 help / color / mirror / Atom feed
From: Lutz Donnerhacke <lutz@iks-jena.de>
Subject: Re: Limited_Controlled types as 'out' arguments
Date: Wed, 30 Jul 2003 15:52:30 +0000 (UTC)
Date: 2003-07-30T15:52:30+00:00	[thread overview]
Message-ID: <slrnbifqdp.o6.lutz@taranis.iks-jena.de> (raw)
In-Reply-To: slrnbiflb5.o6.lutz@taranis.iks-jena.de

* Lutz Donnerhacke wrote:
> * Dmitry A Kazakov wrote:
>> On Wed, 30 Jul 2003 12:32:17 +0000 (UTC), Lutz Donnerhacke
>>>In my implementation, the type Test contains an array_access, I have to
>>>deallocate, before assigning a new value. I can not deallocate this access
>>>variable, because the procedure Free (unchecked_deallocate) requires an
>>>'in out' Parameter. But I only have an 'out' paramter. So I can't read it,
>>>before the first write.
>>
>> You can in Ada 95.
> 
> Oops. Why? This is a clear data flow error, which should be avoided.

To stress this point even more. The approbriate counterpart using assignment
statments and controlled types result in:

------------------------------------------------------------------------
with Ada.Finalization;

package t1 is
   type Char_Access is access Character;
   type Test is new Ada.Finalization.Controlled with record
      a : Char_Access;
   end record;
   procedure Initialize(o : in out Test);
   procedure Finalize(o : in out Test);
   procedure Adjust(o : in out Test);
end t1;
------------------------------------------------------------------------
with t1;
use t1;

procedure t is
   a, b, c : Test;
begin
   a := b;
   a := c;
end t;
------------------------------------------------------------------------
with Ada.Text_IO;
with System.Storage_Elements, System.Address_To_Access_Conversions;
with Unchecked_Deallocation;
use Ada.Text_IO;

package body t1 is
   procedure Debug (msg : String; p : Char_Access) is
      use System.Storage_Elements;
      package Convert is new System.Address_To_Access_Conversions(Character);
   begin
      Put_Line(msg &
        Integer_Address'Image(To_Integer(
            Convert.To_Address(Convert.Object_Pointer(p)))) &
        '(' & p.all & ')');
   end Debug;
   
   global : Character := '0';
   
   procedure Initialize(o : in out Test) is
   begin
      o.a := new Character'(global);
      Debug("Initializing", o.a);
      global := Character'Succ(global);
   end Initialize;
   
   procedure Finalize(o : in out Test) is
      procedure Free is new Unchecked_Deallocation(Character, Char_Access);
   begin
      Debug("Finalizing", o.a);
      Free(o.a);
   end Finalize;
   
   procedure Adjust(o : in out Test) is
      procedure Free is new Unchecked_Deallocation(Character, Char_Access);
      tmp : Char_Access := new Character'(' '); -- occupy some memory
   begin
      Debug("Adjusting from", o.a);
      o.a := new Character'(o.a.all);
      Debug("Adjusting to  ", o.a);
      Free(tmp);
   end Adjust;
end t1;
------------------------------------------------------------------------

Results in:
  Initializing 134630032(0)
  Initializing 134630048(1)
  Initializing 134630064(2)
  Finalizing 134630032(0)
  Adjusting from 134630048(1)
  Adjusting to   134630080(1)
  Finalizing 134630080(1)
  Adjusting from 134630064(2)
  Adjusting to   134630032(2)
  Finalizing 134630064(2)
  Finalizing 134630048(1)
  Finalizing 134630032(2)

Despite the upthead argument "there are only three instances, so finalizing
them suffice", here are also only three instances, which are finalized before
assigment.

Trying it with an 'out' parameter
   procedure Set(o : out Test) is
   begin
      Debug("Setting from", o.a);
      o.a := new Character'(global);
      Debug("Setting to  ", o.a);
      global := Character'Succ(global);
   end Set;
[...]
with t1;
use t1;

procedure t is
   a, b, c : Test;
begin
   a := b;
   a := c;
   Set(a);
   Set(a);
end t;
------------------------------------------------------------------------

gives:
  Initializing 134630064(0)
  Initializing 134630080(1)
  Initializing 134630096(2)
  Finalizing 134630064(0)
  Adjusting from 134630080(1)
  Adjusting to   134630112(1)
  Finalizing 134630112(1)
  Adjusting from 134630096(2)
  Adjusting to   134630064(2)
  Setting from 134630064(2)
  Setting to   134630112(3)
  Setting from 134630112(3)
  Setting to   134630128(4)
  Finalizing 134630096(2)
  Finalizing 134630080(1)
  Finalizing 134630128(4)
  
which is clearly wrong in the same way.

So the only result of this can be: Do not provide 'out' Parameters to
controlled types in the same library unit.



  parent reply	other threads:[~2003-07-30 15:52 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-07-30 11:31 Limited_Controlled types as 'out' arguments Lutz Donnerhacke
2003-07-30 12:22 ` Dmitry A. Kazakov
2003-07-30 12:32   ` Lutz Donnerhacke
2003-07-30 14:24     ` Dmitry A. Kazakov
2003-07-30 14:25       ` Lutz Donnerhacke
2003-07-30 14:48         ` Dmitry A. Kazakov
2003-07-30 15:15           ` Lutz Donnerhacke
2003-07-31 10:26             ` Dmitry A. Kazakov
2003-07-31 10:54               ` Lutz Donnerhacke
2003-07-31 11:50                 ` Dmitry A. Kazakov
2003-07-31 12:19                   ` Lutz Donnerhacke
2003-07-31 13:15                     ` Dmitry A. Kazakov
2003-07-31 17:51                 ` Randy Brukardt
2003-07-30 15:01         ` Vinzent Hoefler
2003-07-30 15:16           ` Lutz Donnerhacke
2003-07-30 15:52         ` Lutz Donnerhacke [this message]
2003-07-30 19:30           ` Randy Brukardt
2003-07-31  7:43             ` Lutz Donnerhacke
2003-07-30 12:31 ` Matthew Heaney
2003-07-30 12:57   ` Lutz Donnerhacke
2003-07-30 13:47     ` Martin Dowie
2003-07-30 17:06     ` Matthew Heaney
2003-07-30 12:37 ` Martin Dowie
2003-07-30 12:59   ` Lutz Donnerhacke
2003-07-30 13:41     ` Martin Dowie
replies disabled

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