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-Thread: 103376,ec3de1b455c3909f X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!postnews.google.com!s33g2000pri.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: unexpected behaviour of finalize Date: Fri, 4 Apr 2008 09:08:28 -0700 (PDT) Organization: http://groups.google.com Message-ID: <308722a0-7372-4a2b-9dbd-8d8704a3fcae@s33g2000pri.googlegroups.com> References: NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: posting.google.com 1207325308 26780 127.0.0.1 (4 Apr 2008 16:08:28 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Fri, 4 Apr 2008 16:08:28 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: s33g2000pri.googlegroups.com; posting-host=66.126.103.122; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.12) Gecko/20050922 Fedora/1.7.12-1.3.1,gzip(gfe),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:20804 Date: 2008-04-04T09:08:28-07:00 List-Id: On Apr 4, 2:33 am, stefan-lu...@see.the.signature wrote: > Hi, > > I have written a little program to demonstrate finalisation. The idea is > to locally declare a singelton object of a class derived from > Ada.Finalization.Limited_Controlled, and to override the Finalize method. > When the sigelton object leaves scope, Finalize than cleans up whatever > needs to be cleaned up. At a first look this appeared to work nicely. But > when done in a recursive subprogram, Finalize rather unexpectedly seems to > always read the local parameters of the innermost scope. > > Here is a test case: > > ---begin fin_test_case.adb > > with Ada.Text_IO, Ada.Finalization; > > procedure Fin_Test_Case is > type Fin is new Ada.Finalization.Limited_Controlled with null record; > > procedure Do_Something (I: Natural) is > > type My_Fin is new Fin with null record; > > overriding procedure Finalize(Self: in out My_Fin) is > S: String := Natural'Image(I); > begin > Ada.Text_IO.Put_Line(" Do_Something Finalization " & S); > end Finalize; > > Singleton: My_Fin; > > begin -- Do_Something > Ada.Text_IO.Put_Line(" I = " & Natural'Image(I)); > if I>0 then > Do_Something(I-1); > Do_Something(I-1); > end if; > end Do_Something; > > begin > Ada.Text_IO.Put_Line("Start Do_Something (2)"); > Do_Something(2); > Ada.Text_IO.Put_Line("Stop Do_Something (2)"); > end Fin_Test_Case; > > ---end fin_test_case.adb > > This is what I got: > > ---begin output > > Start Do_Something (2) > I = 2 > I = 1 > I = 0 > Do_Something Finalization 0 > I = 0 > Do_Something Finalization 0 > Do_Something Finalization 0 > I = 1 > I = 0 > Do_Something Finalization 0 > I = 0 > Do_Something Finalization 0 > Do_Something Finalization 0 > Do_Something Finalization 0 > Stop Do_Something (2) > > ---end output > > Somehow, the local parameter I is always 0 when finalize is called. What I > expected was the following: > > ---begin expected output > > Start Do_Something (2) > I = 2 > I = 1 > I = 0 > Do_Something Finalization 0 > I = 0 > Do_Something Finalization 0 > Do_Something Finalization 1 > I = 1 > I = 0 > Do_Something Finalization 0 > I = 0 > Do_Something Finalization 0 > Do_Something Finalization 1 > Do_Something Finalization 2 > Stop Do_Something (2) > > ---end expected output > > Now, is my expectation wrong? Or is this a compiler bug? I am using > GNAT GPL 2007 (20070405-41). This looks like a pretty clear compiler bug, especially since by the time Finalize is called by the outermost Do_Something, it's using, for the value of I, the parameter from a Do_Something call that is no longer active. It shouldn't be hard to modify this slightly, using (say) a string or record as a parameter to Do_Something, to create a test where utter garbage is displayed; then it would be clearer that this is a compiler bug. -- Adam