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=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no 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!8g2000hse.googlegroups.com!not-for-mail From: george.priv@gmail.com Newsgroups: comp.lang.ada Subject: Re: unexpected behaviour of finalize Date: Fri, 4 Apr 2008 10:38:59 -0700 (PDT) Organization: http://groups.google.com Message-ID: References: <308722a0-7372-4a2b-9dbd-8d8704a3fcae@s33g2000pri.googlegroups.com> NNTP-Posting-Host: 166.129.165.39 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: posting.google.com 1207330739 11436 127.0.0.1 (4 Apr 2008 17:38:59 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Fri, 4 Apr 2008 17:38:59 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: 8g2000hse.googlegroups.com; posting-host=166.129.165.39; posting-account=VnNb3AoAAACTpRtCcTrcjmPX7cs92k1Q User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13,gzip(gfe),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:20812 Date: 2008-04-04T10:38:59-07:00 List-Id: On Apr 4, 12:08 pm, Adam Beneschan wrote: > 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 With little modification: 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(X : natural) is new Fin with null record; overriding procedure Finalize(Self: in out My_Fin) is S: String := Natural'Image(I) & ':' & Natural'Image(Self.X); begin Ada.Text_IO.Put_Line(" Do_Something Finalization " & S); end Finalize; Singleton: My_Fin(i); 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; The result becomes: Start Do_Something (2) I = 2 I = 1 I = 0 Do_Something Finalization 0: 0 I = 0 Do_Something Finalization 0: 0 Do_Something Finalization 0: 1 I = 1 I = 0 Do_Something Finalization 0: 0 I = 0 Do_Something Finalization 0: 0 Do_Something Finalization 0: 1 Do_Something Finalization 0: 2 Stop Do_Something (2) Seems that compiler doing some shortcut with access to wrong I instance