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, T_FILL_THIS_FORM_SHORT autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,57f8540942f8e060,start X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!postnews.google.com!b2g2000yqi.googlegroups.com!not-for-mail From: =?ISO-8859-1?Q?Hibou57_=28Yannick_Duch=EAne=29?= Newsgroups: comp.lang.ada Subject: Initialization and Finalization of limited object "returned" by a function Date: Wed, 10 Feb 2010 20:37:11 -0800 (PST) Organization: http://groups.google.com Message-ID: NNTP-Posting-Host: 86.75.149.114 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 X-Trace: posting.google.com 1265863031 9754 127.0.0.1 (11 Feb 2010 04:37:11 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Thu, 11 Feb 2010 04:37:11 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: b2g2000yqi.googlegroups.com; posting-host=86.75.149.114; posting-account=vrfdLAoAAAAauX_3XwyXEwXCWN3A1l8D User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; fr),gzip(gfe),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:9103 Date: 2010-02-10T20:37:11-08:00 List-Id: Hello boys and girls, I'm actually experiencing an deeply unexpected behavior to me. Let me explain in few words, before you go and dinner with the Test program which will come later soon. Limited types does not know what copy is. I always though a limited type "returned" by a function, was Initialized when it was created and finalized when the scope of its real instance (the function actual invocation's target) was Finalized. What a surprise to me to experience something different : limited object Finalized right after Initialization. The Test program comes as a single file for convenience (the two packages it is built upon are defined in its declarative region). Copy/ paste, name it Test.adb (or any other name if ever you compiler don't like this one), compile and run. Read comments : every things is explained (as well as my initial expectation) in there. Side note : if this was really the legal behavior, I should urgently go back to Ada basics. I will re-check the RM about all of what this story relies anyway. with Ada.Text_IO; -- To give feedback about what's going on. with Ada.Finalization; -- For the implementation of Spies.Instance_Type. procedure Test is -- This Test application exposes an (from the autor -- point of view) unexpected behaviour of limited objects -- "returned" by a function : a case of Finalization -- which occurs right after Initialization, even before -- the function "returning" the limited object -- has terminated. -- -- This Test application is built around Dispatching, -- a package which defines the type which will make -- us meet the latter introduced behaviour, and Spies, -- a package, which will provide us the ability to see -- when exactly objects are Initialized and then Finalized. -- ------------------------------------------------------------- -- Spies package (specification and body) package Spies is -- Provides a spy which is an object you -- may put in any scope (included record, -- protected and task type). It will tell -- tales you of Initialization and -- Finalization of the scope where it -- is intruded. type Instance_Type (Client_Name : access String) is limited private; -- It is limited, so that it could spy scope in -- limited types. -- It will report you what it is experiencing, -- displaying messages on the output stream. The -- message includes the Client_Name, which should -- be the name of a block or the name of a type. private type Instance_Type (Client_Name : access String) is new Ada.Finalization.Limited_Controlled with null record; -- When the host scope will be initialized, -- Limited_Controlled.Initialize will be invoked, -- the same with finalization. This is how -- this spy reports things it is experiencing. overriding procedure Initialize (Instance : in out Instance_Type); overriding procedure Finalize (Instance : in out Instance_Type); end Spies; package body Spies is overriding procedure Initialize (Instance : in out Instance_Type) is Me : Instance_Type renames Instance; begin Ada.Text_IO.Put_Line ("Spy : I am coping Initialization of " & Me.Client_Name.all & "."); end; overriding procedure Finalize (Instance : in out Instance_Type) is Me : Instance_Type renames Instance; begin Ada.Text_IO.Put_Line ("Spy : I am coping with Finalization of " & Me.Client_Name.all & "."); end; end Spies; -- ------------------------------------------------------------- -- Dispatch package (specification and body) package Dispatch is -- Was initialy created to analyze the cause -- of a dispatching failure, thus the name of -- this package; Actually, it exposes an -- unexpected behaviour of limited objects -- created with New_Instance : objects are -- Finalized right after they are Initialized, -- even before the function New_Instance, which -- "returns" a limited type has terminated. -- The action take place in the implementation -- of New_Instance (see the package body). type Instance_Type is synchronized interface; subtype Instance_Class is Instance_Type'Class; procedure P (Instance : in out Instance_Type) is abstract; function New_Instance return Instance_Class; end Dispatch; package body Dispatch is -- For testing purpose, two different implementation -- of Instance_Class was defined. -- ---------------------------------------------------------- -- A_Type protected type A_Type is new Instance_Type with overriding procedure P; private Spy : Spies.Instance_Type (Client_Name => new String'("A_Type")); -- Don't worry about memory leaks : it's for -- testing purpose only. end; protected body A_Type is overriding procedure P is begin Ada.Text_IO.Put_Line ("Invoked P of A_Type."); end; end; -- ---------------------------------------------------------- -- B_Type protected type B_Type is new Instance_Type with overriding procedure P; private Spy : Spies.Instance_Type (Client_Name => new String'("B_Type")); -- Don't worry about memory leaks : it's for -- testing purpose only. end; protected body B_Type is overriding procedure P is begin Ada.Text_IO.Put_Line ("Invoked P of B_Type."); end; end; -- ---------------------------------------------------------- -- Creating instance of the interface's class. function New_A return A_Type is -- Required by the actual GNAT GPL to return -- a class wide type from a function returning -- a limited type. begin return Result : A_Type do null; end return; end; function New_B return B_Type is -- Same motivations as for New_A. begin return Result : B_Type do null; end return; end; function New_Instance return Instance_Class is -- Returns either an A_Type or a B_Type. -- Change the corresponding extended return -- statement to switch from one to another. begin Ada.Text_IO.Put_Line ("New_Instance : Step 1 " & "(before return statement)."); -- Here is where the action takes place. -- The message "Step 1" will be displayed before -- the spy intruded in A_Type, will report -- Initialization of Result. That's OK so far. -- See next step. return Result : Instance_Class := New_A do Ada.Text_IO.Put_Line ("New_Instance : Step 2 " & "(inside of return statement)."); -- The message "Step 2" appears after the -- spy reports Finalization of Result. -- I suppose something is going wrong there, -- as the type is limited, Result is not -- really its instance : its real instance -- the target of the function "returning" -- the limited object. null; end return; end; end Dispatch; -- ------------------------------------------------------------- -- Testing Tested_Interface : Dispatch.Instance_Class := (Dispatch.New_Instance); -- Seems to never come into real existence. begin Dispatch.P (Instance => Tested_Interface); -- This will raise an error, as unfortunately, -- the Tested_Interface instance is already finalized -- at this point (erroneous or legal behavior ?) end Test;