comp.lang.ada
 help / color / mirror / Atom feed
* Initialization and Finalization of limited object "returned" by a function
@ 2010-02-11  4:37 Hibou57 (Yannick Duchêne)
  2010-02-11  9:51 ` Hibou57 (Yannick Duchêne)
                   ` (2 more replies)
  0 siblings, 3 replies; 65+ messages in thread
From: Hibou57 (Yannick Duchêne) @ 2010-02-11  4:37 UTC (permalink / raw)


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;



^ permalink raw reply	[flat|nested] 65+ messages in thread

end of thread, other threads:[~2010-02-14 22:00 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-11  4:37 Initialization and Finalization of limited object "returned" by a function Hibou57 (Yannick Duchêne)
2010-02-11  9:51 ` Hibou57 (Yannick Duchêne)
2010-02-11 11:00 ` Ludovic Brenta
2010-02-11 11:33   ` Jean-Pierre Rosen
2010-02-11 23:15   ` Hibou57 (Yannick Duchêne)
2010-02-11 23:24     ` Robert A Duff
2010-02-12  5:41       ` Hibou57 (Yannick Duchêne)
2010-02-12 15:15         ` Robert A Duff
2010-02-12 16:27           ` Jean-Pierre Rosen
2010-02-12 17:53             ` Jacob Sparre Andersen
2010-02-12 18:05               ` Adam Beneschan
2010-02-13  1:59             ` Randy Brukardt
2010-02-12 16:57           ` Adam Beneschan
2010-02-12 18:07             ` mockturtle
2010-02-12 18:29               ` Hibou57 (Yannick Duchêne)
2010-02-12 19:09             ` Robert A Duff
2010-02-13  2:00               ` Randy Brukardt
2010-02-13  2:51                 ` Hibou57 (Yannick Duchêne)
2010-02-13 15:59                   ` Robert A Duff
2010-02-13 19:34                     ` Hibou57 (Yannick Duchêne)
2010-02-13 19:45                       ` Robert A Duff
2010-02-12 19:10             ` (see below)
2010-02-13  9:54           ` Dmitry A. Kazakov
2010-02-13 15:52             ` (see below)
2010-02-14 10:23               ` Dmitry A. Kazakov
2010-02-13 15:53             ` Robert A Duff
2010-02-14 10:59               ` Dmitry A. Kazakov
2010-02-14 22:00                 ` Hibou57 (Yannick Duchêne)
2010-02-11 15:16 ` Robert A Duff
2010-02-11 17:40   ` Adam Beneschan
2010-02-11 19:10     ` Robert A Duff
2010-02-11 21:51       ` Adam Beneschan
2010-02-11 22:49         ` Hibou57 (Yannick Duchêne)
2010-02-11 22:53           ` Hibou57 (Yannick Duchêne)
2010-02-11 23:08             ` Robert A Duff
2010-02-11 23:18               ` Hibou57 (Yannick Duchêne)
2010-02-12  0:48               ` Randy Brukardt
2010-02-12  5:37               ` Hibou57 (Yannick Duchêne)
2010-02-13  1:54                 ` Randy Brukardt
2010-02-12  5:39               ` Hibou57 (Yannick Duchêne)
2010-02-12 15:10                 ` Robert A Duff
2010-02-12 17:15                   ` (Hibou57) Yannick Duchêne
2010-02-12 19:07                     ` Robert A Duff
2010-02-12  1:05           ` Adam Beneschan
2010-02-12  2:35             ` Hibou57 (Yannick Duchêne)
2010-02-12  2:36               ` Hibou57 (Yannick Duchêne)
2010-02-12  2:36               ` Hibou57 (Yannick Duchêne)
2010-02-12  2:36               ` Hibou57 (Yannick Duchêne)
2010-02-12  2:37               ` Hibou57 (Yannick Duchêne)
2010-02-12  2:37               ` Hibou57 (Yannick Duchêne)
2010-02-12  2:37               ` Hibou57 (Yannick Duchêne)
2010-02-12  4:27                 ` Hibou57 (Yannick Duchêne)
2010-02-12  4:28                   ` Hibou57 (Yannick Duchêne)
2010-02-11 22:53         ` Robert A Duff
2010-02-11 23:41           ` Adam Beneschan
2010-02-12  0:22             ` Robert A Duff
2010-02-12  5:25         ` Hibou57 (Yannick Duchêne)
2010-02-12  9:27         ` Alex R. Mosteo
2010-02-12 16:43           ` Adam Beneschan
2010-02-12 19:11             ` Robert A Duff
2010-02-12  0:44     ` Randy Brukardt
2010-02-12  4:47     ` Hibou57 (Yannick Duchêne)
2010-02-12 18:02       ` Adam Beneschan
2010-02-12  4:49     ` Hibou57 (Yannick Duchêne)
2010-02-12  4:40   ` Hibou57 (Yannick Duchêne)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox