comp.lang.ada
 help / color / mirror / Atom feed
From: Ludovic Brenta <ludovic@ludovic-brenta.org>
Subject: Re: Limited_Controlled, orthogonality and related issues
Date: Thu, 18 Jan 2007 13:00:39 +0100
Date: 2007-01-18T13:00:39+01:00	[thread overview]
Message-ID: <87zm8g4k9k.fsf@ludovic-brenta.org> (raw)
In-Reply-To: eoned5$663$1@cernne03.cern.ch

Maciej Sobczak writes:
> Hi,
>
> Consider the following problem:
>
> package P is
>    type T is limited private;
>    type S is limited private;
>    procedure Do_The_Job(X : in T; Y : in S);
>    -- and gazillion of other subprograms like Do_The_Job
> private
>    -- ...
> end P;
>
> At some point I decide to add automatic destruction to T and S, so the
> package becomes:
>
> with Ada.Finalization;
> package P is
>    type T is limited private;
>    type S is limited private;
>    procedure Do_The_Job(X : in T; Y : in S);
>    -- and gazillion of other subprograms like Do_The_Job
> private
>    type T is new Ada.Finalization.Limited_Controlled with -- ...
>    type S is new Ada.Finalization.Limited_Controlled with -- ...
> end P;
>
> Suddenly, the package no longer compiles:
>
> "operation can be dispatching in only one type"
>
> By making T and S controlled types, they became tagged and Do_The_Job
> is now incorrect.
>
> First observation:
> My design decision to make T and S controlled has absolutely nothing
> to do with Do_The_Job. It relates to those scopes where te objects are
> created, not to those where they are used. It looks that my decision
> affects unrelated parts of the pacakge (Do_The_Job and there are
> gazillions of such subprograms), which is non-sense. There is
> something wrong.
>
> OK, I'm determined to get it done. I do this:
>
>    procedure Do_The_Job(X : in T'Class; Y : in S'Class);
>
> (one would be enough, but let's be symmetric)
>
> Thanks to this, Do_The_Job is no longer dispatching (it was never
> supposed to be, by the way!).
>
> But wait, now there's another problem:
>
> "tagged type required"
>
> It looks like the compiler pretends it doesn't know that T is tagged.
>
> Second observation:
> The compiler does know that T and S are tagged, because it is exactly
> what prevented it to compile Do_The_Job in its original form.
> Now it pretends it has no idea that T and S are tagged, which is
> non-sense number two. Something's completely wrong here.

The types are indeed not tagged in the public part of the package;
only the private part says they're tagged, and Do_The_Job, being
public, has to be consistent with the public declaration of the types.

> But I'm really determined to get it done. I do this:
>
>    type T is tagged limited private;
>    type S is tagged limited private;
>    procedure Do_The_Job(X : in T'Class; Y : in S'Class);
>    -- and gazillion of other subprograms like Do_The_Job
>
> So, my simple decision to make T and S controlled required:
>
> 1. Changing the signatures of Do_The_Job and gazillion of similar
> subprograms.
> 2. Adding the tagged keyword in the public view for T and S.
>
> In conclusion, my decision to make T and S controlled appeared to not
> be orthogonal to the rest of the package.
>
> What are your thoughts about this?

I would have used a mix-in, like so:

with Ada.Finalization;
package P is
   type T is limited private;
   type S is limited private;
   procedure Do_The_Job(X : in T; Y : in S);
   -- and gazillion of other subprograms like Do_The_Job
private
   type T_Finalizer (Enclosing : access T) is
     new Ada.Finalization.Limited_Controlled with null record;

   procedure Finalize (Finalizer : in out T);

   type S_Finalizer (Enclosing : access S) is
     new Ada.Finalization.Limited_Controlled with null record;

   procedure Finalize (Finalizer : in out S);

   type T is record
      -- other components
      Finalizer : T_Finalizer (T'Access);
   end record;

   type S is record
      -- other components
      Finalizer : S_Finalizer (S'Access);
   end record;
end P;

with Ada.Text_IO;
package body P is
   procedure Do_The_Job(X : in T; Y : in S) is
   begin
      Ada.Text_IO.Put_Line ("Doing the job.");
   end Do_The_Job;

   procedure Finalize (Finalizer : in out T) is
   begin
      Ada.Text_IO.Put_Line ("Finalizing a T.");
   end Finalize;


   procedure Finalize (Finalizer : in out S) is
   begin
      Ada.Text_IO.Put_Line ("Finalizing a S.");
   end Finalize;
end P;

with P;
procedure Test is
   My_T : P.T;
   My_S : P.S;
begin
   P.Do_The_Job (My_T, My_S);
end Test;

but the program compiled with GNAT does not display the two
finalization messages.  Bug (i.e. the finalization procedures should
be called as per ARM 7.6.1(9)) or feature (i.e. GNAT optimizes the
calls away, noticing that the program is terminating anyway)?

> Most importantly: why I had to add the tagged keyword?

Because Do_The_Job required the types to be publicly tagged.

-- 
Ludovic Brenta.



  reply	other threads:[~2007-01-18 12:00 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-18  9:24 Limited_Controlled, orthogonality and related issues Maciej Sobczak
2007-01-18 12:00 ` Ludovic Brenta [this message]
2007-01-18 12:33   ` AW: " Grein, Christoph (Fa. ESG)
2007-01-18 16:25   ` Robert A Duff
2007-01-18 17:02 ` Adam Beneschan
2007-01-18 17:16   ` Adam Beneschan
2007-01-19  1:02     ` Robert A Duff
2007-01-19  7:38       ` Maciej Sobczak
2007-01-19  9:05     ` Dmitry A. Kazakov
2007-01-19 17:04       ` Adam Beneschan
2007-01-19  1:01   ` Robert A Duff
2007-01-19  9:57   ` Stephen Leake
2007-01-18 19:03 ` Jeffrey Carter
2007-01-19  7:48 ` Randy Brukardt
2007-01-19 16:46   ` Adam Beneschan
2007-01-19 15:29 ` Robert A Duff
2007-01-19 16:31   ` Dmitry A. Kazakov
2007-01-19 16:36     ` Robert A Duff
2007-01-19 18:26       ` Dmitry A. Kazakov
2007-01-19 20:17         ` Robert A Duff
2007-01-20 10:14           ` Dmitry A. Kazakov
2007-01-20 14:44             ` Robert A Duff
replies disabled

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