Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Ada > Re: unexpected ...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 4 of 7 Topic 5642 of 5966
Post > Topic >>

Re: unexpected behaviour of finalize

by george.priv@[EMAIL PROTECTED] Apr 4, 2008 at 10:38 AM

On Apr 4, 12:08 pm, Adam Beneschan <a...@[EMAIL PROTECTED]
> wrote:
> On Apr 4, 2:33 am, stefan-lu...@[EMAIL PROTECTED]
 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
 




 7 Posts in Topic:
unexpected behaviour of finalize
stefan-lucks@[EMAIL PROTE  2008-04-04 11:33:27 
Re: unexpected behaviour of finalize
Adam Beneschan <adam@[  2008-04-04 09:08:28 
Re: unexpected behaviour of finalize
george.priv@[EMAIL PROTEC  2008-04-04 10:34:29 
Re: unexpected behaviour of finalize
george.priv@[EMAIL PROTEC  2008-04-04 10:38:59 
Re: unexpected behaviour of finalize
stefan-lucks@[EMAIL PROTE  2008-04-04 19:51:28 
Re: unexpected behaviour of finalize
stefan-lucks@[EMAIL PROTE  2008-04-04 19:52:36 
Re: unexpected behaviour of finalize
george.priv@[EMAIL PROTEC  2008-04-04 12:53:36 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Sat Nov 22 11:00:12 CST 2008.