Contents   Index   Search   Previous   Next

4.3.1 Record Aggregates

   [In a record_aggregate, a value is specified for each component of the record or record extension value, using either a named or a positional association.]


record_aggregate ::= (record_component_association_list)
record_component_association_list ::=
    record_component_association {, record_component_association}
  | null record
record_component_association ::=
   [ component_choice_list => ] expression
component_choice_list ::=
     component_selector_name {| component_selector_name}
   | others
{named component association} A record_component_association is a named component association if it has a component_choice_list; {positional component association} otherwise, it is a positional component association. Any positional component associations shall precede any named component associations. If there is a named association with a component_choice_list of others, it shall come last.
Discussion: These rules were implied by the BNF in an early version of the RM9X, but it made the grammar harder to read, and was inconsistent with how we handle discriminant constraints. Note that for array aggregates we still express some of the rules in the grammar, but array aggregates are significantly different because an array aggregate is either all positional (with a possible others at the end), or all named.
In the record_component_association_list for a record_aggregate, if there is only one association, it shall be a named association.
Reason: Otherwise the construct would be interpreted as a parenthesized expression. This is considered a syntax rule, since it is relevant to overload resolution. We choose not to express it with BNF so we can share the definition of record_component_association_list in both record_aggregate and extension_aggregate.
Ramification: The record_component_association_list of an extension_aggregate does not have such a restriction.

Name Resolution Rules

   {expected type (record_aggregate) [partial]} The expected type for a record_aggregate shall be a single nonlimited record type or record extension.
Ramification: This rule is used to resolve whether an aggregate is an array_aggregate or a record_aggregate. The presence of a with is used to resolve between a record_aggregate and an extension_aggregate.
   {needed component (record_aggregate record_component_association_list)} For the record_component_association_list of a record_aggregate, all components of the composite value defined by the aggregate are needed[; for the association list of an extension_aggregate, only those components not determined by the ancestor expression or subtype are needed (see 4.3.2).] Each selector_name in a record_component_association shall denote a needed component [(including possibly a discriminant)].
Ramification: For the association list of a record_aggregate, ``needed components'' includes every component of the composite value, but does not include those in unchosen variants (see AI83-309). If there are variants, then the value specified for the discriminant that governs them determines which variant is chosen, and hence which components are needed.
If an extension defines a new known_discriminant_part, then all of its discriminants are needed in the component association list of an extension aggregate for that type, even if the discriminants have the same names and types as discriminants of the type of the ancestor expression. This is necessary to ensure that the positions in the record_component_association_list are well defined, and that discriminants that govern variant_parts can be given by static expressions.
    {expected type (record_component_association expression) [partial]} The expected type for the expression of a record_component_association is the type of the associated component(s); {associated components (of a record_component_association)} the associated component(s) are as follows:
Ramification: This means that for an association list of an extension_aggregate, only noninherited components are counted to determine the position.

Legality Rules

    If the type of a record_aggregate is a record extension, then it shall be a descendant of a record type, through one or more record extensions (and no private extensions).
    If there are no components needed in a given record_component_association_list, then the reserved words null record shall appear rather than a list of record_component_associations.
Ramification: For example, "(null record)" is a record_aggregate for a null record type. Similarly, "(T'(A) with null record)" is an extension_aggregate for a type defined as a null record extension of T.
    Each record_component_association shall have at least one associated component, and each needed component shall be associated with exactly one record_component_association. If a record_component_association has two or more associated components, all of them shall be of the same type.
Ramification: These rules apply to an association with an others choice.
Reason: Without these rules, there would be no way to know what was the expected type for the expression of the association.
Discussion: AI83-00244 also requires that the expression shall be legal for each associated component. This is because even though two components have the same type, they might have different subtypes. Therefore, the legality of the expression, particularly if it is an array aggregate, might differ depending on the associated component's subtype. However, we have relaxed the rules on array aggregates slightly for Ada 95, so the staticness of an applicable index constraint has no effect on the legality of the array aggregate to which it applies. See 4.3.3. This was the only case (that we know of) where a subtype provided by context affected the legality of an expression.
Ramification: The rule that requires at least one associated component for each record_component_association implies that there can be no extra associations for components that don't exist in the composite value, or that are already determined by the ancestor expression or subtype of an extension_aggregate.
The second part of the first sentence ensures that no needed components are left out, nor specified twice.
    If the components of a variant_part are needed, then the value of a discriminant that governs the variant_part shall be given by a static expression.
Ramification: This expression might either be given within the aggregate itself, or in a constraint on the parent subtype in a derived_type_definition for some ancestor of the type of the aggregate.

Dynamic Semantics

    {evaluation (record_aggregate) [partial]} The evaluation of a record_aggregate consists of the evaluation of the record_component_association_list.
    {evaluation (record_component_association_list) [partial]} For the evaluation of a record_component_association_list, any per-object constraints (see 3.8) for components specified in the association list are elaborated and any expressions are evaluated and converted to the subtype of the associated component. {implicit subtype conversion (expressions in aggregate) [partial]} Any constraint elaborations and expression evaluations (and conversions) occur in an arbitrary order, except that the expression for a discriminant is evaluated (and converted) prior to the elaboration of any per-object constraint that depends on it, which in turn occurs prior to the evaluation and conversion of the expression for the component with the per-object constraint.
Ramification: The conversion in the first rule might raise Constraint_Error.
Discussion: This check in the first rule presumably happened as part of the dependent compatibility check in Ada 83.
    The expression of a record_component_association is evaluated (and converted) once for each associated component.
7  For a record_aggregate with positional associations, expressions specifying discriminant values appear first since the known_discriminant_part is given first in the declaration of the type; they have to be in the same order as in the known_discriminant_part.


    Example of a record aggregate with positional associations:
(4, July, 1776)                                       --  see 3.8 
    Examples of record aggregates with named associations:
(Day => 4, Month => July, Year => 1776)
(Month => July, Day => 4, Year => 1776)
(Disk, Closed, Track => 5, Cylinder => 12)            --  see 3.8.1
(Unit => Disk, Status => Closed, Cylinder => 9, Track => 1)
    Example of component association with several choices:
(Value => 0, Succ|Pred => new Cell'(0, nullnull))   --  see 3.10.1
 --  The allocator is evaluated twice: Succ and Pred designate different cells
    Examples of record aggregates for tagged types (see 3.9 and 3.9.1):
Expression'(null record)
Literal'(Value => 0.0)
Painted_Point'(0.0, Pi/2.0, Paint => Red)

Extensions to Ada 83

{extensions to Ada 83} Null record aggregates may now be specified, via "(null record)". However, this syntax is more useful for null record extensions in extension aggregates.

Wording Changes from Ada 83

Various AIs have been incorporated (AI83-00189, AI83-00244, and AI83-00309). In particular, Ada 83 did not explicitly disallow extra values in a record aggregate. Now we do.

Contents   Index   Search   Previous   Next   Legal