comp.lang.ada
 help / color / mirror / Atom feed
From: Adam Beneschan <adam@irvine.com>
Subject: Re: Indirect visibility of private part in child packages
Date: Thu, 4 Jun 2009 09:06:28 -0700 (PDT)
Date: 2009-06-04T09:06:28-07:00	[thread overview]
Message-ID: <94b5b0e6-eb58-48e7-b140-ed5564e0b344@o14g2000vbo.googlegroups.com> (raw)
In-Reply-To: 77683561-2b21-42c3-8c90-6c08a0c16b99@n21g2000vba.googlegroups.com

On Jun 3, 10:45 pm, Hibou57 (Yannick Duchêne)
<yannick_duch...@yahoo.fr> 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
>    type T1_Type is tagged private;
>    -- Some primitives on T1_Type are specified here ...
> private
>    type T1_Type is tagged record
>       Low_Level_Data : Some_Type;
>    end record; -- T1_Type
> end P1;
> <<<<< --------------------------------------------------
>
> The first child package (with this one, every thing's Ok):>>>>> --------------------------------------------------
>
> package P1.P2 is
>    type T2_Type is new T1_Type with private;
>    -- Some primitives on T2_Type are specified here ...
>    procedure A_Primitive (Item : out T2_Type);
> private
>    type T2_Type is new T1_Type with null record;
> end P1.P2;
>
> package body P1.P2 is
>    procedure A_Primitive (Item : out T2_Type) is
>    begin
>       Item.Low_Level_Data := ...;
>       -- It works, beceause P1.P2 is a child
>       -- package with a view on P1's private part
>    end A_Primitive;
> end P1.P2;
> <<<<< --------------------------------------------------
>
> The second child package (the one which turns into a subtile doubt):>>>>> --------------------------------------------------
>
> with P1.P2;
> package P1.P3 is
>    type T3_Type is new P1.P2.T2_Type with private;
>    -- Some primitives on T2_Type are specified here ...
>    procedure A_Primitive (Item : out T3_Type);
> private
>    type T3_Type is new P1.P2.T2_Type with null record;
> end P1.P3;
>
> package body P1.P3 is
>    procedure A_Primitive (Item : out T3_Type) is
>    begin
>       Item.Low_Level_Data := ...;
>       -- It fails : the compiler complains there is no
>       -- selector "Low_Level_Data" defined for T3_Type
>    end 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




  parent reply	other threads:[~2009-06-04 16:06 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-04  5:45 Indirect visibility of private part in child packages Hibou57 (Yannick Duchêne)
2009-06-04  7:50 ` Ludovic Brenta
2009-06-04 11:47   ` Hibou57 (Yannick Duchêne)
2009-06-04 13:22     ` Robert A Duff
2009-06-04 14:04       ` Hibou57 (Yannick Duchêne)
2009-06-04 16:06 ` Adam Beneschan [this message]
2009-06-04 16:33   ` Hibou57 (Yannick Duchêne)
replies disabled

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