From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,56131a5c3acc678e X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-12-03 06:11:54 PST Path: archiver1.google.com!news2.google.com!fu-berlin.de!news-FFM2.ecrc.net!skynet.be!skynet.be!louie!tjb!not-for-mail Sender: lbrenta@lbrenta Newsgroups: comp.lang.ada Subject: Re: Question about OO programming in Ada References: <8urxb.19482$sb4.18182@newsread2.news.pas.earthlink.net> <1792884.HtYz4Yv8lY@linux1.krischik.com> From: Ludovic Brenta Date: 03 Dec 2003 15:11:51 +0100 Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Organization: -= Belgacom Usenet Service =- NNTP-Posting-Host: 217.136.20.187 X-Trace: 1070460712 reader1.news.skynet.be 2876 217.136.20.187:46439 X-Complaints-To: usenet-abuse@skynet.be Xref: archiver1.google.com comp.lang.ada:3095 Date: 2003-12-03T15:11:51+01:00 List-Id: Dmitry A. Kazakov writes: But the GNAT doc says that deallocation occurs when the storage pool is finalized. Your example does not demonstrate this since your storage pool does not override Finalize. > with Ada.Finalization; > with System; use System; > with System.Storage_Elements; use System.Storage_Elements; > with System.Storage_Pools; use System.Storage_Pools; > package A is > type Misty is > new Ada.Finalization.Limited_Controlled with null record; > procedure Finalize (X : in out Misty); > type Pool is new Root_Storage_Pool with record > Free : Storage_Offset := 1; > Memory : aliased Storage_Array (1..1024); > end record; > procedure Allocate > ( Stack : in out Pool; > Place : out Address; > Size : Storage_Count; > Alignment : Storage_Count > ); > procedure Deallocate > ( Stack : in out Pool; > Place : Address; > Size : Storage_Count; > Alignment : Storage_Count > ); > function Storage_Size (Stack : Pool) return Storage_Count; procedure Finalize (Stack : in out Pool); > end A; > > with Text_IO; use Text_IO; > package body A is > procedure Finalize (X : in out Misty) is > begin > Put_Line ("finalized!"); > end Finalize; > procedure Allocate > ( Stack : in out Pool; > Place : out Address; > Size : Storage_Count; > Alignment : Storage_Count > ) is > begin -- Alignment is ignored for simplicity sake > Put_Line ("Allocated"); > Place := Stack.Memory (Stack.Free)'Address; > Stack.Free := Stack.Free + Size; > end Allocate; > procedure Deallocate > ( Stack : in out Pool; > Place : Address; > Size : Storage_Count; > Alignment : Storage_Count > ) is > begin -- Does nothing > Put_Line ("Deallocated"); > end Deallocate; > function Storage_Size (Stack : Pool) return Storage_Count is > begin > return 0; > end Storage_Size; procedure Finalize (Stack : in out Pool) is begin Put_Line ("Deallocating all objects."); Deallocate (Stack, To_Address (Integer_Address (0)), 0, 0); end Finalize; > end A; > > with A; use A; > with Text_IO; use Text_IO; > procedure Test is > Storage : Pool; > begin > Put_Line ("Begin of a scope"); > declare > type Pointer is access Misty; > for Pointer'Storage_Pool use Storage; > X : Pointer; > begin > X := new Misty; -- This is not dangled! > end; > Put_Line ("End of the scope"); > end Test; > > With GNAT Test should print: > > Begin of a scope > Allocated > finalized! Deallocating all objects. (yes, I tested it) Deallocated > End of the scope > > So even with a user-defined pool it does not work as "should be". > > Of course one could call Unchecked_Deallocation from Finalize as > Pascal noted. But it would be awful for an uncounted number of > reasons. To start with, you never know, who calls Finalize, then you > have no pointer to the object, you can get it, but that will be of a > generic access type, so if you have several pools how do you know, > where the object was allocated? and so on and so far. The finalization is not that of the allocated objects, it is that of the storage pool itself (storage pools are limited controlled). So, this scheme actually works pretty well and is quite straightforward to implement. The part that I do not understand is why GNAT's Unbounded_Reclaim_Pool doesn't seem to be selected for a local access type. I think this either contradicts the GNAT reference manual, or is an instance of me not understanding it. -- Ludovic Brenta.