Contents   Index   Search   Previous   Next
 3.10.1 Incomplete Type Declarations
1
   There are no particular limitations on the designated
type of an access type. In particular, the type of a component of the
designated type can be another access type, or even the same access type.
This permits mutually dependent and recursive access types. An incomplete_type_declaration
can be used to introduce a type to be used as a designated type, while
deferring its full definition to a subsequent full_type_declaration.
Syntax
2
incomplete_type_declaration
::= type defining_identifier [
discriminant_part];
 
Legality Rules
3
   An 
incomplete_type_declaration
requires a completion, which shall be a 
full_type_declaration.
If the 
incomplete_type_declaration
occurs immediately within either the visible part of a 
package_specification
or a 
declarative_part, then the
full_type_declaration shall occur
later and immediately within this visible part or 
declarative_part.
If the 
incomplete_type_declaration
occurs immediately within the private part of a given 
package_specification,
then the 
full_type_declaration shall
occur later and immediately within either the private part itself, or
the 
declarative_part of the corresponding
package_body. 
 
4
   If an 
incomplete_type_declaration
has a 
known_discriminant_part, then
a 
full_type_declaration that completes
it shall have a fully conforming (explicit) 
known_discriminant_part
(see 
6.3.1). 
If an 
incomplete_type_declaration
has no 
discriminant_part (or an
unknown_discriminant_part), then
a corresponding 
full_type_declaration
is nevertheless allowed to have discriminants, either explicitly, or
inherited via derivation.
 
5
   The only allowed
uses of a name that denotes an incomplete_type_declaration
are as follows: 
6
- as the subtype_mark
in the subtype_indication of an
access_to_object_definition; the
only form of constraint allowed
in this subtype_indication is a
discriminant_constraint; 
 
7
- as the subtype_mark
defining the subtype of a parameter or result of an access_to_subprogram_definition;
 
8
- as the subtype_mark
in an access_definition;
 
9
- as the prefix
of an attribute_reference whose
attribute_designator is Class; such
an attribute_reference is similarly
restricted to the uses allowed here; when used in this way, the corresponding
full_type_declaration shall declare
a tagged type, and the attribute_reference
shall occur in the same library unit as the incomplete_type_declaration.
 
10
    A dereference (whether implicit or explicit --
see 
4.1) shall not be of an incomplete type.
 
Static Semantics
11
    An 
incomplete_type_declaration
declares an incomplete type and its first subtype; the first subtype
is unconstrained if a 
known_discriminant_part
appears. 
 
Dynamic Semantics
12
    The elaboration of an 
incomplete_type_declaration
has no effect. 
 
13
80  Within
a declarative_part, an incomplete_type_declaration
and a corresponding full_type_declaration
cannot be separated by an intervening body. This is because a type has
to be completely defined before it is frozen, and a body freezes all
types declared prior to it in the same declarative_part
(see 13.14).  
Examples
14
    Example of a
recursive type: 
15
type Cell;  --  incomplete type declaration
type Link is access Cell;
16
type Cell is
   record
      Value  : Integer;
      Succ   : Link;
      Pred   : Link;
   end record;
17
Head   : Link  := new Cell'(0, null, null);
Next   : Link  := Head.Succ;
18
    Examples of mutually dependent access types:
19
type Person(<>);    -- incomplete type declaration
type Car;           -- incomplete type declaration
20
type Person_Name is access Person;
type Car_Name    is access all Car;
21
type Car is
   record
      Number  : Integer;
      Owner   : Person_Name;
   end record;
22
type Person(Sex : Gender) is
   record
      Name     : String(1 .. 20);
      Birth    : Date;
      Age      : Integer range 0 .. 130;
      Vehicle  : Car_Name;
      case Sex is
         when M => Wife           : Person_Name(Sex => F);
         when F => Husband        : Person_Name(Sex => M);
      end case;
   end record;
23
My_Car, Your_Car, Next_Car : Car_Name := new Car;  -- see 4.8
George : Person_Name := new Person(M);
   ...
George.Vehicle := Your_Car; 
Contents   Index   Search   Previous   Next   Legal