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 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,f93e461e8491e322 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local01.nntp.dca.giganews.com!nntp.scarlet.biz!news.scarlet.biz.POSTED!not-for-mail NNTP-Posting-Date: Thu, 18 Jan 2007 06:01:08 -0600 From: Ludovic Brenta Newsgroups: comp.lang.ada Subject: Re: Limited_Controlled, orthogonality and related issues References: Date: Thu, 18 Jan 2007 13:00:39 +0100 Message-ID: <87zm8g4k9k.fsf@ludovic-brenta.org> User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) Cancel-Lock: sha1:1cuiZKpqrvkfYR4y4bOBo5yIfaI= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii NNTP-Posting-Host: 62.235.206.39 X-Trace: sv3-ZaLaFEP/0ZmDvJhYt0xxq9kIHKWoIhrmhsNmNEKePIqeS493EddjIuhNxx0FkkkH9C4TsZX0/MYqlq6!4rAe8r0tEdzE6ZiFH9Dw2DYZ+qEhTWRv09I2PBYRkVrlylyQh+tehpKmMn3h3OnDtcfqlsVtaA== X-Complaints-To: abuse@scarlet.be X-DMCA-Complaints-To: abuse@scarlet.biz X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.32 Xref: g2news2.google.com comp.lang.ada:8254 Date: 2007-01-18T13:00:39+01:00 List-Id: 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.