Version 1.1 of ais/ai-00157.txt

Unformatted version of ais/ai-00157.txt version 1.1
Other versions for file ais/ai-00157.txt

!standard 07.03 (15)          97-07-04 AI95-00157/03
!class ramification 96-09-04
!status WG9 approved (8-0-0) 97-07-04
!status ARG approved 12-0-0 (subject to editorial review) 96-10-07
!status work item 96-09-08
!status received 96-09-04
!reference AI95-00033
!priority High
!difficulty Hard
!subject Visibility of Inherited Private Components
!summary 96-11-18
Consider types Parent, Child, and Grandchild, derived from one another in that order. The components of Child are determined where Child is declared. If, at the place where Grandchild is declared, additional components of Parent are visible (that were not visible to Child), then Grandchild does not inherit them as visible components. One can convert from Grandchild to Parent in order to manipulate these components.
!question 97-07-04
Consider the following example:
package P is type Parent is tagged private; private type Parent is record C: Integer; end record; end P;
with P; use P; package Q is type Child is new Parent with record C: Integer; end record; end Q;
with Q; use Q; package P.Child is type Grandchild is new Q.Child with null record; X: Grandchild; ... X.C ... end P.Child;
What is the meaning of X.C, given that Grandchild is declared in a place where the full view of Parent is visible?
!response 96-11-18
There is a general rule that you can never have more visibility into the components or operations of a type than in the package where the type is declared. Effectively, the components and operations of a type are "frozen" to be those visible somewhere within the "immediate" scope of the type. Even if you go into a package that knows more about the ancestors of the type, that doesn't change the set of components or primitives that the type has.
So in the above example, the type Child is declared in a place where there is no visibility on the C component of Parent; hence this component is not declared, and it is legal to declare another, unrelated, C component in Parent. Thus, X.C refers to the C component declared in Child. This is despite the fact that at the point of "X.C", it is visible that Child is derived from Parent, and it is visible that Parent has a component called C. To refer to the C component from Parent, one would write Parent(X).C.
The C component from Parent does exist, despite the fact that it is not visible.
This paradox of knowing the ancestry of a type, but not being able to take advantage of it except through explicit conversion, also applied to derived types in Ada 83. It is based on the general notion that even inherited operations and components need to have a point of declaration, and that point of declaration is required to be in the immediate scope of the derived type. If there is no place where such implicit declarations could occur, then the corresponding operations or components are not inherited. (Of course, inherited operations get declared (if at all) in the declarative region containing the type, whereas components get declared (if at all) in the declarative region of the type itself.)
See 7.3.1 and AARM-7.3.1(7.a-7.r).
Consider the following modified example:
package P is type Parent is tagged private; private type Parent is record C: Integer; end record; end P;
package P.Q is type Child is new Parent with record C: Integer; -- Illegal! end record; end P.Q;
The above example is illegal, because in this case, Child does inherit C from Parent, so the second declaration of C is an illegal homograph.
!appendix

!section 7.3(15)
!subject Controversial visibility of inherited private components in a child unit
!reference 96-5635.a Bernard Maudry  96-8-21>>
!reference RM95 7.3 (15) 7.3.1 (3) 7.3.1 (10)
!from Bernard Maudry 96-08-21
!keywords visibility inherited private components child
!discussion

I would like to know if the following code is legal or not as 2 of the 4
compilers
I use think that it is illegal. I will not try to explain you the problem as you
will
better understand it when reading the code below.
package Top is    type Node is abstract tagged private ; private    type Node is
abstract tagged    record       Name : Integer := 0;    end record; end Top ;
package Top.Mid is    type Node is abstract new Top.Node with private ; private
type Node is abstract new Top.Node with    record       Kind : Integer := 0;
end record; end Top.Mid ;  with Top.Mid; generic    type Parent is abstract new
Top.Mid.Node with private; package Top.Extra is    type Node is abstract new
Parent with null record ; end Top.Extra ;  with Top.Mid; with Top.Extra; package
Top.Mid.Extra is new Top.Extra (Parent => Top.Mid.Node);  with Top.Mid.Extra ;
package Top.Mid.Bot is    type Node is new Top.Mid.Extra.Node with null record ;
The_Node : Node ;  private    -- The legality of the two following lines of code
is controversial.    -- Of 4 Ada95 compilers, 2 of them think they are legal,
and the 2 others    -- reject them as illegal.    -- Where is the truth ? Why ?
Buggy_1 : Integer := The_Node.Name;    Buggy_2 : Integer := The_Node.Kind; end
Top.Mid.Bot ;

****************************************************************

!section 7.3(15)
!subject Controversial visibility of inherited private components ...
!reference RM95 7.3 (15) 7.3.1 (3) 7.3.1 (10)
!reference 96-5635.a Bernard Maudry 96-08-21
!from Tucker Taft 96-08-22
!keywords visibility inherited private components child
!reference 96-5636.a Tucker Taft 96-8-22>>
!discussion

> I would like to know if the following code is legal or not as 2 of the 4
> compilers I use think that it is illegal. I will not try to explain
> you the problem as you will better understand it when reading the code below.

[Well, reading the code that appeared below was a bit tricky, given that
it ended up as one long line.  I have reformatted it below.]

package Top is
    type Node is abstract tagged private ;
private
    type Node is abstract tagged
    record
       Name : Integer := 0;
    end record;
end Top ;

package Top.Mid is
    type Node is abstract new Top.Node with private ;
private
    type Node is abstract new Top.Node with
    record
       Kind : Integer := 0;
    end record;
end Top.Mid ;

with Top.Mid;
generic
    type Parent is abstract new Top.Mid.Node with private;
package Top.Extra is
    type Node is abstract new Parent with null record ;
end Top.Extra ;

with Top.Mid;
with Top.Extra;
package Top.Mid.Extra is new Top.Extra (Parent => Top.Mid.Node);

with Top.Mid.Extra ;
package Top.Mid.Bot is
    type Node is new Top.Mid.Extra.Node with null record ;
    The_Node : Node ;
private
    -- The legality of the two following lines of code is controversial.
    -- Of 4 Ada95 compilers, 2 of them think they are legal, and the 2 others
    -- reject them as illegal.
    -- Where is the truth ? Why ?
    Buggy_1 : Integer := The_Node.Name;
    Buggy_2 : Integer := The_Node.Kind;

    -- NOTE: I have added the following two lines:
    Not_Buggy_1 : Integer := Top.Mid.Node(The_Node).Name;
    Not_Buggy_2 : Integer := Top.Mid.Node(The_Node).Kind;
end Top.Mid.Bot ;

========================

The compilers that declare the lines Buggy_1 and Buggy_2 illegal
are operating correctly.  If you want visibility on Name and Kind
you will have to convert the type to Top.Mid.Node, as illustrated
in Not_Buggy_1 and _2.

There is a general rule that you can never have more visibility into
the components or operations of a type that in the package where the
type is declared.  Effectively, the components and operations of
a type are "frozen" to be those visible somewhere within the "immediate"
scope of the type.  Even if you go into a package that knows more about
the ancestors of the type, that doesn't change the set of components or
primitives that the type has.

So in the above case, the type Top.Mid.Extra.Node is declared in
an instance of Top.Extra, where there is no visibility on the
Name or Kind components of the immediate parent type (Top.Mid.Node),
and hence these components are not inherited.  This is despite
the fact that it *is* visible that Top.Mid.Node is derived from
Top.Node, and it *is* visble (inside the implicit private part of Top.Extra)
that Top.Node has a "Name" component.

If you want these components to be inherited, then the generic needs
to be a child of Top.Mid.  Even then, only within the private part
and body of the generic itself, or within the private part or body of
a child of the generic, will these extra components be visible.

Alternately, as illustrated above, you can take advantage of the
fact that these types are visibly derived from Top.Mid.Node, to
convert to Top.Mid.Node and gain visibility on the extra components
in that manner.

This paradox of knowing the ancestry of a type, but not being able
to take advantage of it except through explicit conversion, also
applied to derived types in Ada 83.  It is based on the general notion
that even inherited operations and components need to have a point of
declaration, and that point of declaration is required to be in the
immediate scope of the derived type.  If there is no place where such
implicit declarations could occur, then the corresponding
operations or components are not inherited.

This is discussed in some depth in RM95-7.3.1, and if you have it,
in AARM95-7.3.1(7.a-7.r).

-Tuck

****************************************************************

!section 7.3(15)
!subject Controversial visibility of inherited private components in a child unit
!reference RM95 7.3(15), 7.3.1(3), 7.3.1(10), 8.2(4)
!reference 96-5635.a Bernard Maudry  96-8-21
!from Dan Lehman 96-08-22
!keywords visibility inherited private components child
!reference 96-5639.a Dan Lehman 96-8-22>>
!discussion

   I conclude that the example given by Bernard Maudry in raising this
issue is legal, that both Name & Kind are visible components at the point
where he reports some compilers (names, please?) reporting an illegality
(it would be nice to know what those compilers report!).  Am I missing
something?

   I'll re-cast his example, as the original msg. *disformatted* it
(NB:  I'VE CHANGED THE INSTANCE NAME FROM "EXTRA" TO "LOWER",
which I think will avoid adding confusion re the generic unit "Extra"):

package Top is
    type Node is abstract tagged private ;
 private
    type Node is abstract tagged
    record
       Name : Integer := 0;
    end record; end Top ;

package Top.Mid is
    type Node is abstract new Top.Node with private ;
 private
    type Node is abstract new Top.Node with
    record
       Kind : Integer := 0;
    end record;
 end Top.Mid ;

  with Top.Mid;
 generic
    type Parent is abstract new Top.Mid.Node with private;
 package Top.Extra is
    type Node is abstract new Parent with null record ;
 end Top.Extra ;

  with Top.Mid;
  with Top.Extra;
 package Top.Mid.LOWER is new Top.Extra (Parent => Top.Mid.Node);

  with Top.Mid.LOWER ;
package Top.Mid.Bot is
    type Node is new Top.Mid.LOWER.Node with null record ;
    The_Node : Node ;

  private -- The legality of the two following lines of code is controversial.
          -- Of 4 Ada95 compilers, 2 of them think they are legal,
          --  and the 2 others reject them as illegal.
          -- Where is the truth ? Why ?

    Buggy_1 : Integer := The_Node.Name;   -- LEGAL ??  (yes)
    Buggy_2 : Integer := The_Node.Kind;   -- LEGAL ??  (yes)

 end Top.Mid.Bot ;

I conclude that the controversial lines are legal.  Were "private" removed
from Top.Mid.Bot, then they'd be illegal as per 8.2(4).

---Dan Lehman
-------------- *
=============================================================================

****************************************************************

!section 7.3(15)
!subject Controversial visibility of inherited private components ...
!reference RM95 7.3 (15) 7.3.1(1) 7.3.1 (3) 7.3.1 (6) 7.3.1 (10)
!reference 96-5635.a Bernard Maudry 96-08-21
!reference 96-5636.a Tucker Taft 96-8-22
!from Robert I. Eachus
!keywords visibility inherited private components child
!reference 96-5644.a Robert I. Eachus 96-8-23>>
!discussion

  Tucker Taft said:

  > There is a general rule that you can never have more visibility
  > into the components or operations of a type that in the package
  > where the type is declared.  Effectively, the components and
  > operations of a type are "frozen" to be those visible somewhere
  > within the "immediate" scope of the type.  Even if you go into a
  > package that knows more about the ancestors of the type, that
  > doesn't change the set of components or primitives that the type
  > has.

   This is a nice principle, but I've run into a troubling glitch in
related to it.  It involves pass-through derivation like the original
topic of this comment, but it originally came up in the context of
private operations so I'll frame it there:

   package A is
     type Parent is ...;
   private
     procedure Do_Something(P: in Parent);
   end A;

   package A.B is
     type Child is new A.Parent;
   end A.B;

   package A.B.C is
     type Grandchild is new A.B.Child;
   end A.B.C;

   package body A.B.C is
     Thing: Grandchild;
   begin
     Do_Something(Thing); -- legal?
   end A.B.C;

   The problem is that 7.3.1(6) says:  "Inherited primitive
subprograms follow a different rule.  For a derived_type_definition,
each inherited primitive subprogram is implicitly declared at the
earliest place, if any, within the immediate scope of the the
type_declaration, but after the type_declaration, where the
corresponding declaration from the parent is visible.  If there is no
such place, then the inherited subprogram is not declared at all.  An
inherited subprogram that is not declared at all cannot be named in a
call, and cannot be overridden, but for a tagged type it is possible
to dispatch to it."

   If taken literally, there is no Do_Something for Child, and it
cannot be inherited by Grandchild.  (Of course, this example is
somewhat pathological, since it is always legal to explictly call
Do_Something(Parent(Thing)), but if there are additional dispatching
operations on Parent or Child it does make a difference.)

   I'd like to assume that this is just a glitch, and that there is an
implicit private part but I can't.  7.3.1(1) says: "For a type
declared in the visible part of a package or generic package, certain
operations on the type do not become visible until later in the
package -- either in the private part, or the body."  This seems to
say that if A.B had a body (and other declarations which required
one), then Do_Something for Child would be declared in the body of B,
and certainly wouldn't be available for derivation.

    I'd like to thank Weston T. Pan (westonpa@chaph.usc.edu) for help
in defining this issue.

                                        Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...

****************************************************************

!section 7.3(15)
!subject Controversial visibility of inherited private components ...
!reference RM95 7.3 (15) 7.3.1(1) 7.3.1 (3) 7.3.1 (6) 7.3.1 (10)
!reference 96-5635.a Bernard Maudry 96-08-21
!reference 96-5636.a Tucker Taft 96-8-22
!reference 96-5644.a Robert I. Eachus 96-8-23
!from Gary Dismukes
!keywords visibility inherited private components child
!reference 96-5651.a Gary Dismukes 96-8-25>>
!discussion

Robert Eachus wrote:
>
>    This is a nice principle, but I've run into a troubling glitch in
> related to it.  It involves pass-through derivation like the original
> topic of this comment, but it originally came up in the context of
> private operations so I'll frame it there:
>
>    package A is
>      type Parent is ...;
>    private
>      procedure Do_Something(P: in Parent);
>    end A;
>
>    package A.B is
>      type Child is new A.Parent;
>    end A.B;
>
>    package A.B.C is
>      type Grandchild is new A.B.Child;
>    end A.B.C;
>
>    package body A.B.C is
>      Thing: Grandchild;
>    begin
>      Do_Something(Thing); -- legal?

Yes, this is legal (see below).

>    end A.B.C;
>
>
>    The problem is that 7.3.1(6) says:  "Inherited primitive
> subprograms follow a different rule.  For a derived_type_definition,
> each inherited primitive subprogram is implicitly declared at the
> earliest place, if any, within the immediate scope of the the
> type_declaration, but after the type_declaration, where the
> corresponding declaration from the parent is visible.  If there is no
> such place, then the inherited subprogram is not declared at all.  An
> inherited subprogram that is not declared at all cannot be named in a
> call, and cannot be overridden, but for a tagged type it is possible
> to dispatch to it."
>
>    If taken literally, there is no Do_Something for Child, and it
> cannot be inherited by Grandchild.  (Of course, this example is
> somewhat pathological, since it is always legal to explictly call
> Do_Something(Parent(Thing)), but if there are additional dispatching
> operations on Parent or Child it does make a difference.)

The procedure Do_Something will be inherited for both type Child and
type Grandchild, and declared for each of these types in the (implicit)
private part of the respective package, so the call to Do_Something
in the body of A.B.C is legal.

>    I'd like to assume that this is just a glitch, and that there is an
> implicit private part but I can't.  7.3.1(1) says: "For a type
> declared in the visible part of a package or generic package, certain
> operations on the type do not become visible until later in the
> package -- either in the private part, or the body."  This seems to
> say that if A.B had a body (and other declarations which required
> one), then Do_Something for Child would be declared in the body of B,
> and certainly wouldn't be available for derivation.

The mention of the possibility of operations being declared in a
body doesn't apply to this case.  There are cases where operations
can't be declared until reaching a body, such as for nested packages
followed by types that enable further operations to be declared,
but in the case of your example the types will be declared in the
implicit private part of the package specification since that's
the earliest place where the parent operation is visible.  The
presence of the implicit private part is explicitly defined in
the last sentence of 7.1(6).  So there's no problem with the
operations getting declared in such cases.

Gary Dismukes

****************************************************************

!section 7.3(15)
!subject Controversial visibility of inherited private components ...
!reference RM95 7.3 (15) 7.3.1(1) 7.3.1 (3) 7.3.1 (6) 7.3.1 (10) 7.1(6)
!reference 96-5635.a Bernard Maudry 96-08-21
!reference 96-5636.a Tucker Taft 96-8-22
!reference 96-5644.a Robert I. Eachus 96-8-23
!reference 96-5651.a Gary Dismukes 96-8-25
!from Robert I. Eachus
!keywords visibility inherited private components child
!reference 96-5652.a Robert I. Eachus 96-8-26>>

!discussion

   Gary Dismukes said:

  > ...The presence of the implicit private part is explicitly defined
  > in the last sentence of 7.1(6).  So there's no problem with the
  > operations getting declared in such cases.

   This is probably the right answer, and the one I expected.  But I
still can't read it in 7.1(6) and without help.  For reference:

  RM 7.1(6): "...If the reserved word private does not appear, the
package has an implicit EMPTY private part."

  RM 7.3.1(3..5) talk about "...where additional characteristic become
visible..."

  RM 7.3.1(6) starts out: "Inherited primitive subprograms follow a
different rule.  For a derived_type_definition, each inherited
primitive subprogram is implicitly declared at the earliest place, if
any, within the immediate scope of the type_declaration...An inherited
subprogram that is not declared at all cannot be named in a call and
cannot be overridden, but for a tagged type, it is possible to
dispatch to it."

  So you see my problem.  Is it possible to (implicitly) declare a
derived user subprogram in an implicit private part?  The preamble to
7.3.1(6) and the empty in 7.1(6) encourage me to believe otherwise.
If people think this is a confirmation, fine.  But we got here from a
compiler bug in the non-child package case.

                                        Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...

****************************************************************

!section 7.3(15)
!subject Controversial visibility of inherited private components ...
!reference RM95 7.3 (15) 7.3.1(1) 7.3.1 (3) 7.3.1 (6) 7.3.1 (10) 7.1(6)
!reference 96-5635.a Bernard Maudry 96-08-21
!reference 96-5636.a Tucker Taft 96-8-22
!reference 96-5644.a Robert I. Eachus 96-8-23
!reference 96-5651.a Gary Dismukes 96-8-25
!keywords visibility inherited private components child
!reference 96-5652.a Robert I. Eachus 96-8-26
!from Bob Duff
!reference 96-5655.a Robert A Duff 96-8-27>>

!discussion

>   RM 7.1(6): "...If the reserved word private does not appear, the
> package has an implicit EMPTY private part."
...
>   So you see my problem.  Is it possible to (implicitly) declare a
> derived user subprogram in an implicit private part?

Yes.  I think you're reading too much into the word "empty".  It just
means that "package P is ... end P;" is equivalent to "package P is
... private end P;".  I guess it means, "empty of explicit lexical
elements".  It does contain at least one space character, and it does
contain all kinds of implicit junk, but worrying about that is getting
far too pedantic, I think.  Shall we argue about whether implicit
declarations contain lexical elements and characters and so forth?

>...  The preamble to
> 7.3.1(6) and the empty in 7.1(6) encourage me to believe otherwise.
> If people think this is a confirmation, fine.

I can't think of a better way to say it in English.  If we were writing
a formal definition, we might try to be more precise, but we're not.
Therefore, yes, I think it's a confirmation that an "empty" private part
can contain implicit stuff.  (I mean, think about this: Clearly, an
explicit empty private part can contain implicit declarations.  Unless
you think there's no such thing as an empty private part.)  I believe
one ground rule should be: if we think the RM wording is the best
possible, then we have a confirmation.  Keeping in mind that the average
programmer will understand "empty declarative part" better than some
verbosity like "empty except for the necessary space character, and
perhaps a new-line to obey the formatting rules, and a bunch of implicit
stuff, blah blah blah".

>...  But we got here from a
> compiler bug in the non-child package case.

I would be *extremely* surprised to find that this bug was caused
(twice) by someone reading "empty" in such a pedantic manner.  I would
also be surprised if the bug went away if you added an *explicit* empty
private part.  To me, it just looks like a plain old bug (of which there
are too many in this world).

- Bob

****************************************************************

!section 7.3(15)
!subject Controversial visibility of inherited private components ...
!reference RM95 7.3 (15) 7.3.1(1) 7.3.1 (3) 7.3.1 (6) 7.3.1 (10) 7.1(6)
!reference 96-5635.a Bernard Maudry 96-08-21
!reference 96-5636.a Tucker Taft 96-8-22
!reference 96-5644.a Robert I. Eachus 96-8-23
!reference 96-5651.a Gary Dismukes 96-8-25
!reference 96-5655.a Robert A Duff 96-8-27
!keywords visibility inherited private components child
!reference 96-5652.a Robert I. Eachus 96-8-26
!from Dan Lehman
!reference 96-5661.a Dan Lehman 96-8-28>>

!discussion

Bob D. writes:

> > RM 7.1(6): "...If the reserved word private does not appear, the
> > package has an implicit EMPTY private part."
>
> Yes.  I think you're reading too much into the word "empty".  ...
>
> I can't think of a better way to say it in English.

How about "... an implicit private part"?  One then might naturally expect
an implicit priv. part to contain implicit declarations--each with as many
lexical elements as another (which an implementation may constrain to be
no greater than the number of angels that can dance on the head of a pin
(pin sizes may vary)).  And, more seriously, add "... immediately following
the last lexical element of the visible part."--(so why the "one space"?).

> It does contain at least one space character

I suggest an ACVC implementation-dependent test where code is exactly
the maximum file size and it checks that this guy breaks the limit!
--the resulting FRN would have movie rights!  (-;

---Dan
------- *

****************************************************************

!section 7.3(15)
!subject Controversial visibility of inherited private components ...
!reference RM95 7.3 (15) 7.3.1(1) 7.3.1 (3) 7.3.1 (6) 7.3.1 (10) 7.1(6)
!reference 96-5635.a Bernard Maudry 96-08-21
!reference 96-5636.a Tucker Taft 96-8-22
!reference 96-5644.a Robert I. Eachus 96-8-23
!reference 96-5651.a Gary Dismukes 96-8-25
!reference 96-5655.a Robert A Duff 96-8-27
!reference 96-5652.a Robert I. Eachus 96-8-26
!reference 96-5661.a Dan Lehman 96-8-28
!keywords visibility inherited private components child
!from Robert I. Eachus 96-8-29
!reference 96-5663.a Robert I. Eachus 96-8-29>>

!discussion

     Before everyone gets sick of this topic, I'd like to add a couple
ramifications to the discussion, and make sure everyone agrees with
them.  (I don't think that there is any question in this case of
ambiguity, but they are a somewhat surprising consequence of the
rules...)

     Please don't respond with "Why should that be surprising?" or the
like.  Anyone reading this list should be able to reach exactly the
same conclusions, but there are lesser mortals out there. ;-)  This is
one of those cases where I feel the role of the ARG in issuing
ramifications and confirmations is just as important as the role of
issuing binding interpretations.

Ramification 1:

    package A is
      type Parent is tagged private;
    private
      procedure Do_Something(P: in Parent);
    end A;

    with A; use A;
    package B is
      type Child is new Parent with null record;
    end B;

    package body B is
      Thing: Child;
    begin
      Do_Something(Thing); -- illegal
    end B;

    with B; use B;
    package A.C is
      type Grandchild is new Child with null record;
    end A.C;

    package body A.C is
      Another_Thing: Grandchild;
    begin
      Do_Something(Another_Thing); -- illegal
      Do_Something(Parent'Class(Another_Thing)); -- legal
    end A.C;

----------------------------------------------------------------------------

Ramification 2:

    package A is
      type Parent is tagged private;

      package B is
        type Child is new Parent with null record;
      end B;

    private
      procedure Do_Something(P: in Parent);
    end A;

    package body A is
      package body B is
        -- Do_Something(Child) declared here.
        Thing: Child;
      begin
        Do_Something(Thing); -- legal
      end B;

    end A;

    package A.C is
      use A.B;
      type Grandchild is new Child with null record;
    end A.C;

    package body A.C is
      Another_Thing: Grandchild;
    begin
      Do_Something(Another_Thing); -- illegal
      Do_Something(Parent'Class(Another_Thing)); -- legal
    end A.C;

    This one is the one that bothered me.  If B is a child package,
type Child inherits the private operations on Parent and they can be
further derived.  If B is directly nested, the operations are only
inherited in the body of B.  But if B is out of the direct line, there
are inherited operations that cannot be called explicitly. I do NOT
suggest changing this, and I don't know how to change it without
breaking things.  It is just another case where the structure of
package nesting and child units is important in Ada 95.

****************************************************************

!section 7.3(15)
!subject Controversial visibility of inherited private components ...
!reference RM95 7.3 (15) 7.3.1(1) 7.3.1 (3) 7.3.1 (6) 7.3.1 (10) 7.1(6)
!reference 96-5635.a Bernard Maudry 96-08-21
!reference 96-5636.a Tucker Taft 96-8-22
!reference 96-5644.a Robert I. Eachus 96-8-23
!reference 96-5651.a Gary Dismukes 96-8-25
!reference 96-5655.a Robert A Duff 96-8-27
!reference 96-5652.a Robert I. Eachus 96-8-26
!reference 96-5661.a Dan Lehman 96-8-28
!keywords visibility inherited private components child
!reference 96-5663.a Robert I. Eachus 96-8-29
!from Bob Duff
!reference 96-5667.a Robert A Duff 96-8-30>>

!discussion

>      Before everyone gets sick of this topic, I'd like to add a couple
> ramifications to the discussion, and make sure everyone agrees with
> them.

The ramifications illustrated in your examples are correct (i.e., the
lines marked "-- legal" are legal and the lines marked "-- illegal" are
illegal).

>      Please don't respond with "Why should that be surprising?" or the
> like.

OK.

- Bob

****************************************************************

Questions? Ask the ACAA Technical Agent