comp.lang.ada
 help / color / mirror / Atom feed
From: Dmitry A. Kazakov <mailbox@dmitry-kazakov.de>
Subject: Re: Limited_Controlled types as 'out' arguments
Date: Thu, 31 Jul 2003 13:50:23 +0200
Date: 2003-07-31T13:50:23+02:00	[thread overview]
Message-ID: <s9vhivo9l8pk50sjn0eondi1eotjv2590e@4ax.com> (raw)
In-Reply-To: slrnbihtb3.2j7.lutz@taranis.iks-jena.de

On Thu, 31 Jul 2003 10:54:44 +0000 (UTC), Lutz Donnerhacke
<lutz@iks-jena.de> wrote:

>* Dmitry A Kazakov wrote:
>>>> 1. to leave "out" parameters uninitialized. This is bad.
>>>
>>>This is the most common implementation on most types. (most = unless you
>>>define an Initialize procedure, default component data, or provide
>>>initialization data)
>>
>> No they all are initialized, but probably with a garbage. (:-))
>
>It's not that funny, if you need those data to manage ressources. Managing
>data which is possibly garbage is very hard.

The point is that formally the constructor exists, though does
nothing. So everything is initialized. You might be just unsatisfied
with the way of a particular initialization is done. Well, I was alone
against chorus chanting "we do not need user constructors for all
types". Wellcome in club. (:-))

>>>3) Finalize the current data of the 'limited out' parameter.
>>>   Adjust the assigned data of the 'unlimited out' paramter after return.
>>
>> It would be inconsistent. Adjust is called after a raw copy is made,
>> your subprogram uses a valid type interface instead. And you better
>> don't do it after Finalize [+ other destructors] were called. Consider
>> a task object as a member of your limited type.
>
>I still do not get it completely.
>
>------------------------------------------------------------------------
>with Ada.Finalization;
>
>package t1 is
>   type Char_Access is access Character;
>   type Test is new Ada.Finalization.Limited_Controlled with record
>      a : Char_Access;
>   end record;
>   procedure Initialize(o : in out Test);
>   procedure Finalize(o : in out Test);
>   procedure Set(o1, o2 : out Test; i : Test);
>end t1;
>------------------------------------------------------------------------
>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 Free is new Unchecked_Deallocation(Character, Char_Access);
>   procedure Finalize(o : in out Test) is
>   begin
>      Debug("Finalizing  ", o.a);
>      Free(o.a);
>   end Finalize;
>   
>   procedure Set(o1, o2 : out Test; i : Test) is
>   begin
>      Debug("Setting from", i.a);
>      Debug("Setting o1  ", o1.a);
>      Debug("Setting o2  ", o2.a);
>      Finalize(o1);
>      Finalize(o2);
>      
>      o1.a := new Character'(global);
>      Debug("Setting to1 ", o1.a);
>      global := Character'Succ(global);
>
>      o2.a := new Character'(i.a.all);
>      Debug("Setting to2 ", o2.a);
>   end Set;
>end t1;
>------------------------------------------------------------------------
>with t1;
>use t1;
>
>procedure t is
>   a, b : Test;
>begin
>   Set(a, a, b);
>end t;
>------------------------------------------------------------------------
>
>Results in:
>Initializing 134630800(0)
>Initializing 134630816(1)
>Setting from 134630816(1)
>Setting o1   134630800(0)
>Setting o2   134630800(0)
>Finalizing   134630800(0)
>raised PROGRAM_ERROR : t1.adb:14
>Finalizing   134630816(1)
>
>I'am mad?

Sort of, if you are calling Finalize from a normal subprogram! (:-))
As for error, you call Set (a, a, b); which finalizes a twice! It is a
language design fault that a destructor can be called explicitly. Your
example shows why.

---
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



  reply	other threads:[~2003-07-31 11:50 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 [this message]
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
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