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,FREEMAIL_FROM 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-04 13:32:20 PST Path: archiver1.google.com!news2.google.com!newsfeed2.dallas1.level3.net!news.level3.com!crtntx1-snh1.gtei.net!news.gtei.net!newsfeed1.easynews.com!easynews.com!easynews!small1.nntp.aus1.giganews.com!border1.nntp.aus1.giganews.com!intern1.nntp.aus1.giganews.com!nntp.giganews.com!nntp.comcast.com!news.comcast.com.POSTED!not-for-mail NNTP-Posting-Date: Thu, 04 Dec 2003 15:32:18 -0600 Date: Thu, 04 Dec 2003 16:32:17 -0500 From: "Robert I. Eachus" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax) X-Accept-Language: en-us, en MIME-Version: 1.0 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> <1070466281.168920@master.nyc.kbcfp.com> <1070490862.478119@master.nyc.kbcfp.com> <2prtsvgmt5lt3u1ulb5dvh8ba5nulfl3l3@4ax.com> In-Reply-To: <2prtsvgmt5lt3u1ulb5dvh8ba5nulfl3l3@4ax.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Message-ID: NNTP-Posting-Host: 24.34.214.193 X-Trace: sv3-fOTmMK3jWT8ZfGdmTWh8VDyTHEOW0lHbA48sKOEL2nR9GEoiazifPXkgZ7ngpYc1NkmYVabsCSZomut!PWs3NEfaUe5HbcZaH5WUrd3ATltlRJdlPJKIS+Ri1VoDS1cGopxoIsMtj3YLZw== X-Complaints-To: abuse@comcast.net X-DMCA-Complaints-To: dmca@comcast.net X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.1 Xref: archiver1.google.com comp.lang.ada:3136 Date: 2003-12-04T16:32:17-05:00 List-Id: Dmitry A. Kazakov wrote: > On Wed, 03 Dec 2003 20:23:53 -0500, "Robert I. Eachus" > wrote: > > >>Hyman Rosen wrote: >> >> >>>Not on a pointer field within the object, but on the object itself. >> >>I'm very confused about why Hyman is confused. Making a copy of an >>access value in Ada, and calling Free for both the original and the copy >>is bad juju. Calling Free twice, or twenty times and passing the only >>the original access object is never a problem. > > > It is worth to write a sample code to the problem: > > with Ada.Finalization;... > > The point is that calling Free from Finalize is revolting. Yes, that is exactly the code you should never write. If you have an object which is always designated by an access value, and you want the object to be deallocated "automagically," the Ada solution is to make the access variable a component of a record: with Ada.Finalization; package B is type Object_Ref is new Ada.Finalization.Limited_Controlled with private; record Got_It : Boolean := False; -- Prevents recursion end record; procedure Finalize (X : in out Object); private type Object is limited...; type Object_Ptr is access Object'Class; type Object_Ref is new Ada.Finalization.Limited_Controlled with record Obj: Object_Ptr := new Object; end record; end B; with Ada.Unchecked_Deallocation; with Text_IO; use Text_IO; package body B is procedure Free is new Ada.Unchecked_Deallocation (Object_Ref'Class, Object_Ptr); procedure Finalize (X : in out Object_Ref) is begin Free (X.Obj); Put_Line ("Deallocation"); end Finalize; end B; with B; use B; with Text_IO; use Text_IO; procedure Test1 is begin Put_Line ("Begin of the scope"); declare X : Object_Ref; -- allocation done here. begin null; end; -- Finalize called here. Put_Line ("End of the scope"); end Test1; There are lots of variations on this theme, including a version where Object_Ref is not limited and there is an Adjust, or where the allocator is in an Initialize routine. But this is the standard Ada 95 idiom for managing objects which must be on the stack. The "pointer type" is a controlled record with an access type to the 'real' data on the heap. But notice that the original version is a live hand grenade that can be set off in three ways. If you create a Object on the stack, if an Object is not properly initialized, or if Finalize gets called more than once. The 'clever' code to check Got_It is no real protection in the third case. The storage designated by a junk pointer can have any value for Got_It. In the second case, it may prevent deallocating an object that was never initialized, but that is a relatively minor problem (storage leak) compared to the other failure cases. > This would > not be necessary if finalization of the type Pointer called > deallocator in addition to a call to Finalize. Think about this for a second, because there is a germ of a good idea here. For access types for which assignment is valid, such a rule would be a disaster. For example you don't want the next record in a linked list, and for that matter all of the rest of the list, deallocated if you remove an item from a list. However, in my example above, the Object_Ref type is declared as limited. What if we had true limited access types? type Pointer is limited access Object; For such a type deallocating the designated memory when the Pointer object goes away would make sense. I just don't think it is a necessary language extension since it is so easy to create the abstraction when needed. (And besides, there are many cases where you want the type to appear limited to users, but where you actually want to do assignment in the package body.) -- Robert I. Eachus 100% Ada, no bugs--the only way to create software.