Contents   Index   Previous   Next


3.8 Record Types

1
   {record} {record type} A record object is a composite object consisting of named components. The value of a record object is a composite value consisting of the values of the components. {structure: See record type}

Syntax

2
record_type_definition ::= [[abstracttagged] [limitedrecord_definition
3
record_definition ::=
    record
       component_list
    end record
  | null record
4
component_list ::=
      component_item {component_item}
   | {component_itemvariant_part
   |  null;
5/1
{8652/0009} component_item ::= component_declaration | aspect_clauserepresentation_clause
6
component_declaration ::=
   defining_identifier_list : component_definition [:= default_expression];

Name Resolution Rules

7
   {expected type (component_declaration default_expression) [partial]} The expected type for the default_expression, if any, in a component_declaration is the type of the component.

Legality Rules

8
   A default_expression is not permitted if the component is of a limited type.
9
   {components (of a record type) [partial]} Each component_declaration declares a component of the record type. Besides components declared by component_declarations, the components of a record type include any components declared by discriminant_specifications of the record type declaration. [The identifiers of all components of a record type shall be distinct.]
9.a
Proof: The identifiers of all components of a record type have to be distinct because they are all declared immediately within the same declarative region. See Section 8.
10
    Within a type_declaration, a name that denotes a component, protected subprogram, or entry of the type is allowed only in the following cases:
11
12
12.a
Reason: The penultimate restriction simplifies implementation, and allows the outer discriminant and the inner discriminant or bound to possibly share storage.
12.b
Ramification: Other rules prevent such a discriminant from being an inherited one.
12.c
Reason: The last restriction is inherited from Ada 83. The restriction is not really necessary from a language design point of view, but we did not remove it, in order to avoid unnecessary changes to existing compilers.
12.d
Discussion: Note that a discriminant can be used to define the constraint for a component that is of an access-to-composite type.
12.e
Reason: The above rules, and a similar one in 6.1 for formal parameters, are intended to allow initializations of components or parameters to occur in an arbitrary order -- whatever order is most efficient, since one default_expression cannot depend on the value of another one. It also prevent circularities.
12.f
Ramification: Inherited discriminants are not allowed to be denoted, except within representation items. However, the discriminant_selector_name of the parent subtype_indication is allowed to denote a discriminant of the parent.
13
    If the name of the current instance of a type (see 8.6) is used to define the constraint of a component, then it shall appear as a direct_name that is the prefix of an attribute_reference whose result is of an access type, and the attribute_reference shall appear alone.
13.a
Reason: This rule allows T'Access or T'Unchecked_Access, but disallows, for example, a range constraint (1..T'Size). Allowing things like (1..T'Size) would mean that a per-object constraint could affect the size of the object, which would be bad.

Static Semantics

14
    {nominal subtype (of a record component) [partial]} The component_definition of a component_declaration defines the (nominal) subtype of the component. If the reserved word aliased appears in the component_definition, then the component is aliased (see 3.10).
14.a
Ramification: In this case, the nominal subtype cannot be an unconstrained discriminated subtype. See 3.6.
15
    {null record} If the component_list of a record type is defined by the reserved word null and there are no discriminants, then the record type has no components and all records of the type are null records. A record_definition of null record is equivalent to record null; end record.
15.a
Ramification: This short-hand is available both for declaring a record type and a record extension -- see 3.9.1.

Dynamic Semantics

16
    {elaboration (record_type_definition) [partial]} The elaboration of a record_type_definition creates the record type and its first subtype, and consists of the elaboration of the record_definition. {elaboration (record_definition) [partial]} The elaboration of a record_definition consists of the elaboration of its component_list, if any.
17
    {elaboration (component_list) [partial]} The elaboration of a component_list consists of the elaboration of the component_items and variant_part, if any, in the order in which they appear. {elaboration (component_declaration) [partial]} The elaboration of a component_declaration consists of the elaboration of the component_definition.
17.a
Discussion: If the defining_identifier_list has more than one defining_identifier, we presume here that the transformation explained in 3.3.1 has already taken place. Alternatively, we could say that the component_definition is elaborated once for each defining_identifier in the list.
18/1
      {8652/0002} {per-object expression} {per-object constraint} {entry index subtype} Within the definition of a composite type, if a component_definition or discrete_subtype_definition (see 9.5.2) includes a name that denotes a discriminant of the type, or that is an attribute_reference whose prefix denotes the current instance of the type, the expression containing the name is called a per-object expression, and the constraint or rangeconstraint being defined is called a per-object constraint. {elaboration (component_definition) [partial]} For the elaboration of a component_definition of a component_declaration or the discrete_subtype_definition of an entry_declaration for an entry family (see 9.5.2), if the constraint or range of the subtype_indication or discrete_subtype_definition is not a per-object constraint, then the subtype_indication or discrete_subtype_definition is elaborated. On the other hand, if the constraint or range is a per-object constraint, then the elaboration consists of the evaluation of any included expression that is not part of a per-object expression. Each such expression is evaluated once unless it is part of a named association in a discriminant constraint, in which case it is evaluated once for each associated discriminant.
18.1/1
        {8652/0002} {Elaboration (per-object constraint) [partial]} When a per-object constraint is elaborated [(as part of creating an object)], each per-object expression of the constraint is evaluated. For other expressions, the values determined during the elaboration of the component_definition or entry_declaration are used. Any checks associated with the enclosing subtype_indication or discrete_subtype_definition are performed[, including the subtype compatibility check (see 3.2.2),] and the associated subtype is created.
18.a
Discussion: The evaluation of other expressions that appear in component_definitions and discrete_subtype_definitions is performed when the type definition is elaborated. The evaluation of expressions that appear as default_expressions is postponed until an object is created. Expressions in representation items that appear within a composite type definition are evaluated according to the rules of the particular representation item.
NOTES
19
55  A component_declaration with several identifiers is equivalent to a sequence of single component_declarations, as explained in 3.3.1.
20
56  The default_expression of a record component is only evaluated upon the creation of a default-initialized object of the record type (presuming the object has the component, if it is in a variant_part -- see 3.3.1).
21
57  The subtype defined by a component_definition (see 3.6) has to be a definite subtype.
22
58  If a record type does not have a variant_part, then the same components are present in all values of the type.
23
59  A record type is limited if it has the reserved word limited in its definition, or if any of its components are limited (see 7.5).
24
60  {predefined operations (of a record type) [partial]} The predefined operations of a record type include membership tests, qualification, and explicit conversion. If the record type is nonlimited, they also include assignment and the predefined equality operators.
25
61  A component of a record can be named with a selected_component. A value of a record can be specified with a record_aggregate, unless the record type is limited.

Examples

26
    Examples of record type declarations:
27
type Date is
   record
      Day   : Integer range 1 .. 31;
      Month : Month_Name;
      Year  : Integer range 0 .. 4000;
   end record;
28
type Complex is
   record
      Re : Real := 0.0;
      Im : Real := 0.0;
   end record;
29
    Examples of record variables:
30
Tomorrow, Yesterday : Date;
A, B, C : Complex;
31
-- both components of A, B, and C are implicitly initialized to zero 

Extensions to Ada 83

31.a
{extensions to Ada 83} The syntax rule for component_declaration is modified to use component_definition (instead of component_subtype_definition). The effect of this change is to allow the reserved word aliased before the component_subtype_definition.
31.b
A short-hand is provided for defining a null record type (and a null record extension), as these will be more common for abstract root types (and derived types without additional components).
31.c
The syntax rule for record_type_definition is modified to allow the reserved words tagged and limited. Tagging is new. Limitedness is now orthogonal to privateness. In Ada 83 the syntax implied that limited private was sort of more private than private. However, limitedness really has nothing to do with privateness; limitedness simply indicates the lack of assignment capabilities, and makes perfect sense for nonprivate types such as record types.

Wording Changes from Ada 83

31.d/1
{8652/0009} The syntax rules now allow aspect_clausesrepresentation_clauses to appear in a record_definition. This is not a language extension, because Legality Rules prevent all language-defined representation clauses from appearing there. However, an implementation-defined attribute_definition_clause could appear there. The reason for this change is to allow the rules for aspect_clausesrepresentation_clauses and representation pragmas to be as similar as possible.

Contents   Index   Previous   Next   Legal