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: a07f3367d7,f473cbaae52e095d X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII Path: g2news2.google.com!postnews.google.com!o14g2000vbo.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: Indirect visibility of private part in child packages Date: Thu, 4 Jun 2009 09:06:28 -0700 (PDT) Organization: http://groups.google.com Message-ID: <94b5b0e6-eb58-48e7-b140-ed5564e0b344@o14g2000vbo.googlegroups.com> References: <77683561-2b21-42c3-8c90-6c08a0c16b99@n21g2000vba.googlegroups.com> NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1244131589 6823 127.0.0.1 (4 Jun 2009 16:06:29 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Thu, 4 Jun 2009 16:06:29 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: o14g2000vbo.googlegroups.com; posting-host=66.126.103.122; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618),gzip(gfe),gzip(gfe) Xref: g2news2.google.com comp.lang.ada:6256 Date: 2009-06-04T09:06:28-07:00 List-Id: On Jun 3, 10:45=A0pm, Hibou57 (Yannick Duch=EAne) wrote: > Hi all, > > I've meet a tortuous question with a set of packages I'm converting > from Pascal (as I use Ada now, I'm taking the opportunity to re-create > a nicer design). > > The question I'm facing deals with visibility of private part in child > package. More precisely, an indirect visibility of a private part. An > exemple will better show the case: > > This can be reduced to three package (specs and bodies) > > The root package: > > >>>>> -------------------------------------------------- > > package P1 is > =A0 =A0type T1_Type is tagged private; > =A0 =A0-- Some primitives on T1_Type are specified here ... > private > =A0 =A0type T1_Type is tagged record > =A0 =A0 =A0 Low_Level_Data : Some_Type; > =A0 =A0end record; -- T1_Type > end P1; > <<<<< -------------------------------------------------- > > The first child package (with this one, every thing's Ok):>>>>> ---------= ----------------------------------------- > > package P1.P2 is > =A0 =A0type T2_Type is new T1_Type with private; > =A0 =A0-- Some primitives on T2_Type are specified here ... > =A0 =A0procedure A_Primitive (Item : out T2_Type); > private > =A0 =A0type T2_Type is new T1_Type with null record; > end P1.P2; > > package body P1.P2 is > =A0 =A0procedure A_Primitive (Item : out T2_Type) is > =A0 =A0begin > =A0 =A0 =A0 Item.Low_Level_Data :=3D ...; > =A0 =A0 =A0 -- It works, beceause P1.P2 is a child > =A0 =A0 =A0 -- package with a view on P1's private part > =A0 =A0end A_Primitive; > end P1.P2; > <<<<< -------------------------------------------------- > > The second child package (the one which turns into a subtile doubt):>>>>>= -------------------------------------------------- > > with P1.P2; > package P1.P3 is > =A0 =A0type T3_Type is new P1.P2.T2_Type with private; > =A0 =A0-- Some primitives on T2_Type are specified here ... > =A0 =A0procedure A_Primitive (Item : out T3_Type); > private > =A0 =A0type T3_Type is new P1.P2.T2_Type with null record; > end P1.P3; > > package body P1.P3 is > =A0 =A0procedure A_Primitive (Item : out T3_Type) is > =A0 =A0begin > =A0 =A0 =A0 Item.Low_Level_Data :=3D ...; > =A0 =A0 =A0 -- It fails : the compiler complains there is no > =A0 =A0 =A0 -- selector "Low_Level_Data" defined for T3_Type > =A0 =A0end A_Primitive; > end P1.P3; > <<<<< -------------------------------------------------- > > As said in the last comment, it seems P1.P3 cannot see the > T1_Type.Low_Level_Data member. But as P3 is a child package of P1, it > has a view on P1's private part, and there is indeed no trouble about > it with P2. P3 know P2.T2_Type is derived from P1.T1_Type, and P3 has > a view on T1_Type privates. But it seems the compiler does not care > about it. > > There may be interpretation matter here : does the private > specification, means "disallow access to private part" or does it > means "do not provide an access to the private part". If it means > "disallow access to private part", then it ill explain why P3 cannot > access T1_Type.Low_Level_Data member. But if it means "do no provide > an access to private" part, then P3 should still be able to access > T1.Low_Level_Data, beceause it has an access to this as a child > package of P1. > > What does long experienced lawyers think about it ? Here's why it doesn't work: The "operation" of providing a selector Low_Level_Data for T1_Type is made visible in the private part of P1. When T2_Type is declared as derived from T1_Type, the operation of providing the selector Low_Level_Data is inherited from T1_Type, but it only becomes visible where the original operation becomes visible. Since the original operation is visible in the private part of P1, the inherited operation becomes visible in the private part of P1.P2, which is the first place that the private part of P1 is visible. (It's not relevant that T2_Type is a private extension; I believe it would work the same if T2_Type were fully declared in the visible part.) When T3_Type is declared as derived as T2_Type, the operation of providing the selector Low_Level_Data is inherited from T2_Type, but it only becomes visible where the original operation (on T2_Type!!) becomes visible, which is... nowhere, because there isn't anywhere in P1.P3 that is able to access P1.P2's private part (and according to the above paragraph, that's where the operation on T2_Type is made visible---in P1.P2's private part). That's why Low_Level_Data isn't available for T3_Type. So the compiler is correct to reject your original program. However, I think Ludovic's fix (using a type conversion, actually a view conversion) should work, and it's a compiler bug if that is rejected. One could argue that this rule is anomalous, and that if a type is visibly derived from a grandparent (or great-grandparent, etc.) type in a situation like this, then operations that are indirectly inherited from the grandparent (etc.) type should be visible if they're visible for the grandparent, even if the inheritance comes indirectly through a non-visible part of some other package. There could be a privacy problem if the operation could be overridden in the non-visible part, but that isn't possible here---there's nothing P1.P2 can do to change the meaning of the Low_Level_Data selector. This issue is related to AI05-125, but although a couple of us think there's a flaw in the language, others believe that it can't be fixed without making things even more confusing. In any event, it's not all that important here since the view conversion is an adequate workaround, assuming your compiler isn't broken. > I've try to look in section 8 of the "RM 2005", but either the answer > was not there or else, I missed it. I think 7.3.1 and particularly 7.3.1(4) is the important rule here, although I have to admit that that section uses a lot of slightly fuzzy generalities that I've had problems interpreting occasionally. -- Adam