Version 1.8 of ais/ai-00033.txt

Unformatted version of ais/ai-00033.txt version 1.8
Other versions for file ais/ai-00033.txt

!standard 07.03.01 (03)          99-10-07 AI95-00033/07
!standard 07.03.01 (04)
!standard 07.03.01 (05)
!standard 07.03.01 (06)
!class binding interpretation 95-06-25
!status Corrigendum 2000 99-07-28
!status WG9 approved 96-12-07
!status ARG approved 11-0-0 96-10-07
!status work item (letter ballot was 1-8-2) 96-06-05
!status ARG approved (subject to letter ballot) 8-0-2 95-11-01
!status received 95-06-25
!reference AI95-00157
!priority High
!difficulty Medium
!qualifier Error
!subject Delayed declaration of inherited primitive subprograms
!summary
7.3.1 describes places where additional characteristics of a type become revealed. These rules apply only immediately within the declarative region in which the type is declared.
!question
Is the rule given in 7.3.1(6) intended to apply to cases where a derived type is declared outside the declarative region in which its parent type is immediately declared? (No.)
Consider the following example:
package body R is
package P is type Pt is ...; private procedure Op (X : Pt); end P;
type T is new P.Pt; -- procedure Op (X : T); is inherited here but not yet declared
package body P is -- procedure Op (X : T) is declared here, according to -- 7.3.1(6), because the corresponding declaration for Pt -- is visible at this point and the body of P is still within -- the immediate scope of T. It is somewhat strange, however, -- that the subprogram does not get declared immediately -- within the same declarative region as T. -- Is this the intent? (No.) begin Op(T'(...)); -- Legal? (No.) end P;
end R;
Also, are the rules of 7.3.1(3) and 7.3.1(4) regarding the availability of additional characteristics for composite types and derived types intended to apply when such types are declared outside the declarative region in which a component type or parent type is immediately declared? (No.)
!recommendation
(See summary.)
!wording
In paragraphs 7.3.1(3,4,5,6) replace wording of the form "within the immediate scope of the type" with "immediately within the declarative region in which the type is declared". Alternatively, provide a prefatory paragraph that specifies that the rules apply only when the composite or derived type is declared within the same declarative region as the type from which it inherits additional operations and characteristics.
!discussion
The wording of 7.3.1 was inherited from the Ada 83 standard's subsection 7.4.2, but by stating the rules in terms of the immediate scope of the type this inadvertently included all nested scopes, which was not intended.
Consider:
package Outer is package Inner is type Inner_Type is private; private type Inner_Type is new Boolean; end Inner;
type Outer_Type is array(Natural range <>) of Inner.Inner_Type; end Outer;
package body Outer is package body Inner is ... -- At this point, we can see that Inner_Type is a Boolean type. -- So does Outer_Type have an "and" operator here? (No.) end Inner; end Outer;
The wording of 7.3.1(3) would seem to imply that an "and" operator is implicitly declared for type Outer_Type at the beginning of the body of Inner, since this is within the immediate scope of Outer_Type. However, in Ada 83, such an "and" operator was not implicitly declared -- such an operator could only be declared immediately within the declarative region of Outer_Type -- not in some nested Inner package.
This language change was not intended. Furthermore, the principle that implicit declarations of operators (or other additional characteristics) can only be revealed immediately within the declaration region of the outer type should be preserved, even in the case of new language features, such as child packages. Therefore, 7.3.1(3,4,5,6) are changed accordingly.
The Ada 83 standard prefaced paragraph 7.4.2(6) by saying, "If the composite type is itself declared within the package that declares the private type", which avoided the problems introduced by 7.3.1(3,4,6). In attempting to be more general and include derived types as well as composite types, plus handle the case of child units (which are not "within" their parent package but are "within the declarative region of" their parent), the restriction imposed by the Ada 83 preface was unintentionally lost. Note that the AARM does not list this as a "Change from Ada 83", which is further evidence that this change was not intended. Also, paragraph 7.3.1(7.b) of the AARM makes it clear that these rules were only meant to pertain to types declared within the same declarative region as the component type or parent type providing the additional operations.
!corrigendum 7.3.1(3)
Replace the paragraph:
For a composite type, the characteristics (see 7.3) of the type are determined in part by the characteristics of its component types. At the place where the composite type is declared, the only characteristics of component types used are those characteristics visible at that place. If later within the immediate scope of the composite type additional characteristics become visible for a component type, then any corresponding characteristics become visible for the composite type. Any additional predefined operators are implicitly declared at that place.
by:
For a composite type, the characteristics (see 7.3) of the type are determined in part by the characteristics of its component types. At the place where the composite type is declared, the only characteristics of component types used are those characteristics visible at that place. If later immediately within the declarative region in which the composite type is declared additional characteristics become visible for a component type, then any corresponding characteristics become visible for the composite type. Any additional predefined operators are implicitly declared at that place.
!corrigendum 7.3.1(4)
Replace the paragraph:
The corresponding rule applies to a type defined by a derived_type_definition, if there is a place within its immediate scope where additional characteristics of its parent type become visible.
by:
The corresponding rule applies to a type defined by a derived_type_definition, if there is a place immediately within the declarative region in which the type is declared where additional characteristics of its parent type become visible.
!corrigendum 7.3.1(5)
Replace the paragraph:
For example, an array type whose component type is limited private becomes nonlimited if the full view of the component type is nonlimited and visible at some later place within the immediate scope of the array type. In such a case, the predefined "=" operator is implicitly declared at that place, and assignment is allowed after that place.
by:
For example, an array type whose component type is limited private becomes nonlimited if the full view of the component type is nonlimited and visible at some later place immediately within the declarative region in which the array type is declared. In such a case, the predefined "=" operator is implicitly declared at that place, and assignment is allowed after that place.
!corrigendum 7.3.1(6)
Replace the paragraph:
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, 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.
by:
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, immediately within the declarative region in which the type_declaration occurs, 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.
!ACATS test
Create a B-test to insure that additional operators and operations are not defined when they are not supposed to be defined.
!appendix

!section 7.3.1(7)
!section 7.3.1(7)
!subject delayed declaration of inherited primitive subprograms
!reference AARM-7.3.1(7);6.0
!reference AARM-7.3.1(7b);6.0
!from Jesper Joergensen 95-03-29
!keywords
!reference as: 95-5108.a Jesper Joergensen 95-3-31>>
!discussion

As I understand the rules in 7.3.1(6) they need not necessarily apply
to the case where the derived type is declared within the declarative region
of the package that declares the parent type (as 7.3.1(7b) claims they do).

Consider:

   package body R is

      package P is
         type Pt is ..
      private
         procedure Op( X : Pt );
      end P;

      type T is new P.Pt;   -- We are NOT in the declarative region of P

      package body p is
         -- procedure Op( X : T ) is declared implicitly here because now
         -- the corresponding declaration for Pt is visible and we are
         -- still in the immediate scope of T.
         -- It is somewhat strange, however, that the subprogram does not
         -- get declared in the same declarative region as T.
      end p;

   end R;

Is 7.3.1(7b) wrong or am I misunderstanding 7.3.1(6)?

/Jesper

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

!section 7.3.1(7)
!section 7.3.1(7)
!subject delayed declaration of inherited primitive subprograms
!reference AARM-7.3.1(7);6.0
!reference AARM-7.3.1(7b);6.0
!reference RM83-7.4.2(7)
!reference 95-5108.a Jesper Joergensen 95-03-29
!from Tucker Taft 95-03-31
!reference as: 95-5110.a Tucker Taft 95-3-31>>
!discussion

> As I understand the rules in 7.3.1(6) they need not necessarily apply
> to the case where the derived type is declared within the declarative region
> of the package that declares the parent type (as 7.3.1(7b) claims they do).

The wording of 7.3.1 was inherited from RM83 7.4.2, but as you point
out, the term "within the immediate scope of the type" actually includes all
nested scopes as well.  The correct wording would be "immediately
within the declarative region in which the type was declared."

The "meta rule" is that no user of a type should have more operations
available on it than those available somewhere immediately within the
package in which the type was immediately declared.

> Consider:
>
>    package body R is
>
>       package P is
>          type Pt is ..
>       private
>          procedure Op( X : Pt );
>       end P;
>
>       type T is new P.Pt;   -- We are NOT in the declarative region of P
>
>       package body p is
>          -- procedure Op( X : T ) is declared implicitly here because now
>          -- the corresponding declaration for Pt is visible and we are
>          -- still in the immediate scope of T.
>          -- It is somewhat strange, however, that the subprogram does not
>          -- get declared in the same declarative region as T.

This was not the intent, but you are correct that the wording
implies this.  The wording (inherited from Ada 83) was meant
to apply only to points immediately within the declarative region
in which the composite/derived type was immediately declared.

It was always the intent that implicit declarations of operations
(or other "characteristics") of a type could occur only immediately within
the same declarative region as the type declaration.

RM83 prefaced paragraph 7.4.2(6) by "If the composite type is itself
declared within the package that declares the private type" so
using the phrase "within the immediate scope" would not suffer
from the above problem.  Unfortunately, in our attempt to be more
general and include derived types as well as composite types, and handle
the case of child units (which are not "within" their parent package but are
"within the declarative region of" their parent), we simply left out the
critical preface.  We should have prefaced 7.3.1(3-7) by saying that we
are only talking about cases where the composite/derived
type is declared within the declarative region of the package where
some private component/parent type is declared (or use the longer-winded
"immediately within the declarative region in which the composite/derived
type was immediately declared").

>       end p;
>
>    end R;
>
> Is 7.3.1(7b) wrong or am I misunderstanding 7.3.1(6)?

You are wrong, but you are not misunderstanding the words,
only the intent of 7.3.1(6) ;-).  It should only apply
within the declarative region of the package in which some
component/parent private type was declared.

> /Jesper

-Tucker Taft   stt@inmet.com
Intermetrics, Inc.

P.S. So much for "partial reuse" of RM83 wording... -T

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

Questions? Ask the ACAA Technical Agent