Spec-Zone.ru › Ada 2022
Ada Reference Manual (Ada 2022)

3.10.1 Incomplete Type Declarations

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

incomplete_type_declaration ::=
type defining_identifier [discriminant_part] [is tagged];

Static Semantics

An incomplete_type_declaration declares an incomplete view of a type and its first subtype; the first subtype is unconstrained if a discriminant_part appears. If the incomplete_type_declaration includes the reserved word tagged, it declares a tagged incomplete view. If T denotes a tagged incomplete view, then T'Class denotes a tagged incomplete view. An incomplete view of a type is a limited view of the type (see 7.5).
Given an access type A whose designated type T is an incomplete view, a dereference of a value of type A also has this incomplete view except when:
  • it occurs within the immediate scope of the completion of T, or
  • it occurs within the scope of a nonlimited_with_clause that mentions a library package in whose visible part the completion of T is declared, or
  • it occurs within the scope of the completion of T and T is an incomplete view declared by an incomplete_type_declaration.
In these cases, the dereference has the view of T visible at the point of the dereference.
Similarly, if a subtype_mark denotes a subtype_declaration defining a subtype of an incomplete view T, the subtype_mark denotes an incomplete view except under the same three circumstances given above, in which case it denotes the view of T visible at the point of the subtype_mark.

Legality Rules

An incomplete_type_declaration requires a completion, which shall be a type_declaration other than an incomplete_type_declaration. If the incomplete_type_declaration occurs immediately within either the visible part of a package_specification or a declarative_part, then the 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 type_declaration shall occur later and immediately within either the private part itself, or the declarative_part of the corresponding package_body.
If an incomplete_type_declaration includes the reserved word tagged, then a type_declaration that completes it shall declare a tagged type. If an incomplete_type_declaration has a known_discriminant_part, then a 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 type_declaration is nevertheless allowed to have discriminants, either explicitly, or inherited via derivation.
A name that denotes an incomplete view of a type may be used as follows:
  • 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 (a null_exclusion is not allowed);
  • as the subtype_mark in the subtype_indication of a subtype_declaration; the subtype_indication shall not have a null_exclusion or a constraint;
  • as the subtype_mark in an access_definition for an access-to-object type;
  • as the subtype_mark defining the subtype of a parameter or result in a profile occurring within a basic_declaration;
  • as a generic actual parameter whose corresponding generic formal parameter is a formal incomplete type (see 12.5.1).
If such a name denotes a tagged incomplete view, it may also be used:
  • as the subtype_mark defining the subtype of a parameter in the profile for a subprogram_body, entry_body, or accept_statement;
  • as the prefix of an attribute_reference whose attribute_designator is Class; such an attribute_reference is restricted to the uses allowed here; it denotes a tagged incomplete view.
This paragraph was deleted.
  • This paragraph was deleted.
If any of the above uses occurs as part of the declaration of a primitive subprogram of the incomplete view, and the declaration occurs immediately within the private part of a package, then the completion of the incomplete view shall also occur immediately within the private part; it shall not be deferred to the package body.
No other uses of a name that denotes an incomplete view of a type are allowed.
A prefix that denotes an object shall not be of an incomplete view. An actual parameter in a call shall not be of an untagged incomplete view. The result object of a function call shall not be of an incomplete view. A prefix shall not denote a subprogram having a formal parameter of an untagged incomplete view, nor a return type that is an incomplete view.
The controlling operand or controlling result of a dispatching call shall not be of an incomplete view if the operand or result is dynamically tagged.
Paragraph 11 was deleted.

Dynamic Semantics

The elaboration of an incomplete_type_declaration has no effect.
NOTE 1 Within a declarative_part, an incomplete_type_declaration and a corresponding full_type_declaration cannot be separated by an intervening body. This is because, by the rules given in 13.14, a type is illegal if it is not completely defined before it is frozen, and a body freezes all types declared prior to it in the same declarative_part.
NOTE 2 A name that denotes an object of an incomplete view is defined to be of a limited type. Hence, the target of an assignment statement cannot be of an incomplete view.

Examples

Example of a recursive type:
type Cell; -- incomplete type declaration
type Link is access Cell;
type Cell is
record
Value : Integer;
Succ : Link;
Pred : Link;
end record;
Head : Link := new Cell'(0, null, null);
Next : Link := Head.Succ;
Examples of mutually dependent access types:
type Person(<>); -- incomplete type declaration
type Car is tagged; -- incomplete type declaration
type Person_Name is access Person;
type Car_Name is access all Car'Class;
type Car is tagged
record
Number : Integer;
Owner : Person_Name;
end record;
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;
My_Car, Your_Car, Next_Car : Car_Name := new Car; -- see 4.8
Casey : Person_Name := new Person(M);
...
Casey.Vehicle := Your_Car;


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API