Go to the first, previous, next, last section, table of contents.


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 section 6.3.1 Conformance Rules. 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:
    1. 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;
    2. as the subtype_mark defining the subtype of a parameter or result of an access_to_subprogram_definition;
    3. as the subtype_mark in an access_definition;
    4. 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.

  1. A dereference (whether implicit or explicit -- See section 4.1 Names.) shall not be of an incomplete type.

    Static Semantics

  2. 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

  3. The elaboration of an incomplete_type_declaration has no effect.

    NOTES

  4. (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 section 13.14 Freezing Rules.

    Examples

  5. Example of a recursive type:
  6. type Cell;  --  incomplete type declaration
    type Link is access Cell;
    
  7. type Cell is
       record
          Value  : Integer;
          Succ   : Link;
          Pred   : Link;
       end record;
    
  8. Head   : Link  := new Cell'(0, null, null);
    Next   : Link  := Head.Succ;
    
  9. Examples of mutually dependent access types:
  10. type Person(<>);    -- incomplete type declaration
    type Car;           -- incomplete type declaration
    
  11. type Person_Name is access Person;
    type Car_Name    is access all Car;
    
  12. type Car is
       record
          Number  : Integer;
          Owner   : Person_Name;
       end record;
    
  13. 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;
    
  14. My_Car, Your_Car, Next_Car : Car_Name := new Car;
    -- See section 4.8 Allocators
    George : Person_Name := new Person(M);
       ...
    George.Vehicle := Your_Car;
    


Go to the first, previous, next, last section, table of contents.