[Home] [Prev] [Next] [Index]

4.3 Aggregates

4.3 Aggregates

1
[An aggregate combines component values into a composite value of an array type, record type, or record extension.]

Syntax

2
aggregate ::= record_aggregate | extension_aggregate | array_aggregate

Name Resolution Rules

3
The expected type for an aggregate shall be a single nonlimited array type, record type, or record extension.

3.a
Discussion:  See 8.6, "The Context of Overload Resolution" for the meaning of "shall be a single ... type."

Legality Rules

4
An aggregate shall not be of a class-wide type.

4.a
Ramification: When the expected type in some context is class-wide, an aggregate has to be explicitly qualified by the specific type of value to be created, so that the expected type for the aggregate itself is specific.

4.b
Discussion:  We used to disallow aggregates of a type with unknown discriminants.  However, that was unnecessarily restrictive in the case of an extension aggregate, and irrelevant to a record aggregate (since a type that is legal for a record aggregate could not possibly have unknown discriminants) and to an array aggregate (the only specific types that can have unknown discriminants are private types, private extensions, and types derived from them).

Dynamic Semantics

5
For the evaluation of an aggregate, an anonymous object is created and values for the components or ancestor part are obtained (as described in the subsequent subclause for each kind of the aggregate) and assigned into the corresponding components or ancestor part of the anonymous object. Obtaining the values and the assignments occur in an arbitrary order. The value of the aggregate is the value of this object.

5.a
Discussion:  The ancestor part is the set of components inherited from the ancestor type.  The syntactic category ancestor_part is the expression or subtype_mark that specifies how the ancestor part of the anonymous object should be initialized.

5.b
Ramification: The assignment operations do the necessary value adjustment, as described in 7.6. Note that the value as a whole is not adjusted - just the subcomponents (and ancestor part, if any). 7.6 also describes when this anonymous object is finalized.

5.c
If the ancestor_part is a subtype_mark the Initialize procedure for the ancestor type is applied to the ancestor part after default-initializing it, unless the procedure is abstract, as described in 7.6. The Adjust procedure for the ancestor type is not called in this case, since there is no assignment to the ancestor part as a whole.

6
If an aggregate is of a tagged type, a check is made that its value belongs to the first subtype of the type. Constraint_Error is raised if this check fails.

6.a
Ramification: This check ensures that no values of a tagged type are ever outside the first subtype, as required for inherited dispatching operations to work properly (see 3.4).  This check will always succeed if the first subtype is unconstrained. This check is not extended to untagged types to preserve upward compatibility.

Extensions to Ada 83

6.b
We now allow extension_aggregates.

Wording Changes From Ada 83

6.c
We have adopted new wording for expressing the rule that the type of an aggregate shall be determinable from the outside, though using the fact that it is nonlimited record (extension) or array.

6.d
An aggregate now creates an anonymous object. This is necessary so that controlled types will work (see 7.6).

4.3.1 Record Aggregates

1
[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.]

Syntax

2
record_aggregate ::= (record_component_association_list)

3
record_component_association_list ::=
    record_component_association {, record_component_association}
  | null record

4
record_component_association ::=
   [ component_choice_list => ] expression

5
component_choice_list ::=
     component_selector_name {| component_selector_name}
   | others

6
A record_component_association is a named component association if it has a component_choice_list; 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.

6.a
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.

7
In the record_component_association_list for a record_aggregate, if there is only one association, it shall be a named association.

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

7.b
Ramification: The record_component_association_list of an extension_aggregate does not have such a restriction.

Name Resolution Rules

8
The expected type for a record_aggregate shall be a single nonlimited record type or record extension.

8.a
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.

9
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)].

9.a
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 AI-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.

9.b
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.

10
The expected type for the expression of a record_component_association is the type of the associated component(s); the associated component(s) are as follows:

11 ·
For a positional association, the component [(including possibly a discriminant)] in the corresponding relative position (in the declarative region of the type), counting only the needed components;

11.a
Ramification: This means that for an association list of an extension_aggregate, only noninherited components are counted to determine the position.

12 ·
For a named association with one or more component_selector_names, the named component(s);

13 ·
For a named association with the reserved word others, all needed components that are not associated with some previous association.

Legality Rules

14
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).

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

15.a
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.

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

16.a
Ramification: These rules apply to an association with an others choice.

16.b
Reason: Without these rules, there would be no way to know what was the expected type for the expression of the association.

16.c
Discussion:  AI-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 9X, 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.

16.d
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.

16.e
The second part of the first sentence ensures that no needed components are left out, nor specified twice.

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

17.a
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

18
The evaluation of a record_aggregate consists of the evaluation of the record_component_association_list.

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

19.a
Ramification: The conversion might raise Constraint_Error.

19.b
Discussion:  This check presumably happened as part of the dependent compatibility check in Ada 83.

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.

20
The expression of a record_component_association is evaluated (and converted) once for each associated component.

NOTES

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

Examples

22
Example of a record aggregate with positional associations:

23
(4, July, 1776)                                       --  see 3.8

24
Examples of record aggregates with named associations:

25
(Day => 4, Month => July, Year => 1776)
(Month => July, Day => 4, Year => 1776)

26
(Disk, Closed, Track => 5, Cylinder => 12)            --  see 3.8.1
(Unit => Disk, Status => Closed, Cylinder => 9, Track => 1)

27
Example of component association with several choices:

28
(Value => 0, Succ|Pred => new Cell'(0, null, null))   --  see 3.10.1

29
--  The allocator is evaluated twice:  Succ and Pred designate different cells

30
Examples of record aggregates for tagged types (see 3.9 and 3.9.1):

31
Expression'(null record)
Literal'(Value => 0.0)
Painted_Point'(0.0, Pi/2.0, Paint => Red)

Extensions to Ada 83

31.a
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

31.b
Various AIs have been incorporated (AI-189, AI-244, and AI-309). In particular, Ada 83 did not explicitly disallow extra values in a record aggregate.  Now we do.

4.3.2 Extension Aggregates

1
[An extension_aggregate specifies a value for a type that is a record extension by specifying a value or subtype for an ancestor of the type, followed by associations for any components not determined by the ancestor_part.]

Language Design Principles

1.a
The model underlying this syntax is that a record extension can also be viewed as a regular record type with an ancestor "prefix." The record_component_association_list corresponds to exactly what would be needed if there were no ancestor/prefix type. The ancestor_part determines the value of the ancestor/prefix.

Syntax

2
extension_aggregate ::=
    (ancestor_part with record_component_association_list)

3
ancestor_part ::= expression | subtype_mark

Name Resolution Rules

4
The expected type for an extension_aggregate shall be a single nonlimited type that is a record extension. If the ancestor_part is an expression, it is expected to be of any nonlimited tagged type.

4.a
Reason: We could have made the expected type T'Class where T is the ultimate ancestor of the type of the aggregate, or we could have made it even more specific than that.  However, if the overload resolution rules get too complicated, the implementation gets more difficult and it becomes harder to produce good error messages.

Legality Rules

5
If the ancestor_part is a subtype_mark, it shall denote a specific tagged subtype. The type of the extension_aggregate shall be derived from the type of the ancestor_part, through one or more record extensions (and no private extensions).

Static Semantics

6
For the record_component_association_list of an extension_aggregate, the only components needed are those of the composite value defined by the aggregate that are not inherited from the type of the ancestor_part, plus any inherited discriminants if the ancestor_part is a subtype_mark that denotes an unconstrained subtype.

Dynamic Semantics

7
For the evaluation of an extension_aggregate, the record_component_association_list is evaluated. If the ancestor_part is an expression, it is also evaluated; if the ancestor_part is a subtype_mark, the components of the value of the aggregate not given by the record_component_association_list are initialized by default as for an object of the ancestor type. Any implicit initializations or evaluations are performed in an arbitrary order, except that the expression for a discriminant is evaluated prior to any other evaluation or initialization that depends on it.

8
If the type of the ancestor_part has discriminants that are not inherited by the type of the extension_aggregate, then, unless the ancestor_part is a subtype_mark that denotes an unconstrained subtype, a check is made that each discriminant of the ancestor has the value specified for a corresponding discriminant, either in the record_component_association_list, or in the derived_type_definition for some ancestor of the type of the extension_aggregate. Constraint_Error is raised if this check fails.

8.a
Ramification: Corresponding and specified discriminants are defined in 3.7. The rules requiring static compatibility between new discriminants of a derived type and the parent discriminant(s) they constrain ensure that at most one check is required per discriminant of the ancestor expression.

NOTES

9 8
If all components of the value of the extension_aggregate are determined by the ancestor_part, then the record_component_association_list is required to be simply null record.

10 9
If the ancestor_part is a subtype_mark, then its type can be abstract.  If its type is controlled, then as the last step of evaluating the aggregate, the Initialize procedure of the ancestor type is called, unless the Initialize procedure is abstract (see 7.6).

Examples

11
Examples of extension aggregates (for types defined in 3.9.1):

12
Painted_Point'(Point with Red)
(Point'(P) with Paint => Black)

13
(Expression with Left => 1.2, Right => 3.4)
Addition'(Binop with null record)
             -- presuming Binop is of type Binary_Operation

Extensions to Ada 83

13.a
The extension aggregate syntax is new.

4.3.3 Array Aggregates

1
[In an array_aggregate, a value is specified for each component of an array, either positionally or by its index.] For a positional_array_aggregate, the components are given in increasing-index order, with a final others, if any, representing any remaining components. For a named_array_aggregate, the components are identified by the values covered by the discrete_choices.

Language Design Principles

1.a
The rules in this subclause are based on terms and rules for discrete_choice_lists defined in 3.8.1, "Variant Parts and Discrete Choices".

Syntax

2
array_aggregate ::=
  positional_array_aggregate | named_array_aggregate

3
positional_array_aggregate ::=
    (expression, expression {, expression})
  | (expression {, expression}, others => expression)

4
named_array_aggregate ::=
    (array_component_association {, array_component_association})

5
array_component_association ::=
    discrete_choice_list => expression

6
An n-dimensional array_aggregate is one that is written as n levels of nested array_aggregates (or at the bottom level, equivalent string_literals). For the multidimensional case (n >= 2) the array_aggregates (or equivalent string_literals) at the n-1 lower levels are called subaggregates of the enclosing n-dimensional array_aggregate. The expressions of the bottom level subaggregates (or of the array_aggregate itself if one-dimensional) are called the array component expressions of the enclosing n-dimensional array_aggregate.

6.a
Ramification: Subaggregates do not have a type.  They correspond to part of an array.  For example, with a matrix, a subaggregate would correspond to a single row of the matrix. The definition of "n-dimensional" array_aggregate applies to subaggregates as well as aggregates that have a type.

6.b
To be honest: An others choice is the reserved word others as it appears in a positional_array_aggregate or as the discrete_choice of the discrete_choice_list in an array_component_association.

Name Resolution Rules

7
The expected type for an array_aggregate (that is not a subaggregate) shall be a single nonlimited array type. The component type of this array type is the expected type for each array component expression of the array_aggregate.

7.a
Ramification: We already require a single array or record type or record extension for an aggregate. The above rule requiring a single nonlimited array type (and similar ones for record and extension aggregates) resolves which kind of aggregate you have.

8
The expected type for each discrete_choice in any discrete_choice_list of a named_array_aggregate is the type of the corresponding index; the corresponding index for an array_aggregate that is not a subaggregate is the first index of its type; for an (n-m)-dimensional subaggregate within an array_aggregate of an n-dimensional type, the corresponding index is the index in position m+1.

Legality Rules

9
An array_aggregate of an n-dimensional array type shall be written as an n-dimensional array_aggregate.

9.a
Ramification: In an m-dimensional array_aggregate [(including a subaggregate)], where m >= 2, each of the expressions has to be an (m-1)-dimensional subaggregate.

10
An others choice is allowed for an array_aggregate only if an applicable index constraint applies to the array_aggregate. [An applicable index constraint is a constraint provided by certain contexts where an array_aggregate is permitted that can be used to determine the bounds of the array value specified by the aggregate.] Each of the following contexts (and none other) defines an applicable index constraint:

11 ·
For an explicit_actual_parameter, an explicit_generic_actual_parameter, the expression of a return_statement, the initialization expression in an object_declaration, or a default_expression [(for a parameter or a component)], when the nominal subtype of the corresponding formal parameter, generic formal parameter, function result, object, or component is a constrained array subtype, the applicable index constraint is the constraint of the subtype;

12 ·
For the expression of an assignment_statement where the name denotes an array variable, the applicable index constraint is the constraint of the array variable;

12.a
Reason: This case is broken out because the constraint comes from the actual subtype of the variable (which is always constrained) rather than its nominal subtype (which might be unconstrained).

13 ·
For the operand of a qualified_expression whose subtype_mark denotes a constrained array subtype, the applicable index constraint is the constraint of the subtype;

14 ·
For a component expression in an aggregate, if the component's nominal subtype is a constrained array subtype, the applicable index constraint is the constraint of the subtype;

14.a
Discussion:  Here, the array_aggregate with others is being used within a larger aggregate.

15 ·
For a parenthesized expression, the applicable index constraint is that, if any, defined for the expression.

15.a
Discussion:  RM83 omitted this case, presumably as an oversight.  We want to minimize situations where an expression becomes illegal if parenthesized.

16
The applicable index constraint applies to an array_aggregate that appears in such a context, as well as to any subaggregates thereof. In the case of an explicit_actual_parameter (or default_expression) for a call on a generic formal subprogram, no applicable index constraint is defined.

16.a
Reason: This avoids generic contract model problems, because only mode conformance is required when matching actual subprograms with generic formal subprograms.

17
The discrete_choice_list of an array_component_association is allowed to have a discrete_choice that is a nonstatic expression or that is a discrete_range that defines a nonstatic or null range, only if it is the single discrete_choice of its discrete_choice_list, and there is only one array_component_association in the array_aggregate.

17.a
Discussion:  We now allow a nonstatic others choice even if there are other array component expressions as well.

18
In a named_array_aggregate with more than one discrete_choice, no two discrete_choices are allowed to cover the same value (see 3.8.1); if there is no others choice, the discrete_choices taken together shall exactly cover a contiguous sequence of values of the corresponding index type.

18.a
Ramification: This implies that each component must be specified exactly once.  See AI-309.

19
A bottom level subaggregate of a multidimensional array_aggregate of a given array type is allowed to be a string_literal only if the component type of the array type is a character type; each character of such a string_literal shall correspond to a defining_character_literal of the component type.

Static Semantics

20
A subaggregate that is a string_literal is equivalent to one that is a positional_array_aggregate of the same length, with each expression being the character_literal for the corresponding character of the string_literal.

Dynamic Semantics

21
The evaluation of an array_aggregate of a given array type proceeds in two steps:

22 1.
Any discrete_choices of this aggregate and of its subaggregates are evaluated in an arbitrary order, and converted to the corresponding index type;

23 2.
The array component expressions of the aggregate are evaluated in an arbitrary order and their values are converted to the component subtype of the array type; an array component expression is evaluated once for each associated component.

23.a
Ramification: Subaggregates are not separately evaluated. The conversion of the value of the component expressions to the component subtype might raise Constraint_Error.

24
The bounds of the index range of an array_aggregate [(including a subaggregate)] are determined as follows:

25 ·
For an array_aggregate with an others choice, the bounds are those of the corresponding index range from the applicable index constraint;

26 ·
For a positional_array_aggregate [(or equivalent string_literal)] without an others choice, the lower bound is that of the corresponding index range in the applicable index constraint, if defined, or that of the corresponding index subtype, if not; in either case, the upper bound is determined from the lower bound and the number of expressions [(or the length of the string_literal)];

27 ·
For a named_array_aggregate without an others choice, the bounds are determined by the smallest and largest index values covered by any discrete_choice_list.

27.a
Reason: We don't need to say that each index value has to be covered exactly once, since that is a ramification of the general rule on aggregates that each component's value has to be specified exactly once.

28
For an array_aggregate, a check is made that the index range defined by its bounds is compatible with the corresponding index subtype.

28.a
Discussion:  In RM83, this was phrased more explicitly, but once we define "compatibility" between a range and a subtype, it seems to make sense to take advantage of that definition.

28.b
Ramification: The definition of compatibility handles the special case of a null range, which is always compatible with a subtype.  See AI-00313.

29
For an array_aggregate with an others choice, a check is made that no expression is specified for an index value outside the bounds determined by the applicable index constraint.

29.a
Discussion:  RM83 omitted this case, apparently through an oversight.  AI-309 defines this as a dynamic check, even though other Ada 83 rules ensured that this check could be performed statically. We now allow an others choice to be dynamic, even if it is not the only choice, so this check now needs to be dynamic, in some cases.  Also, within a generic unit, this would be a nonstatic check in some cases.

30
For a multidimensional array_aggregate, a check is made that all subaggregates that correspond to the same index have the same bounds.

30.a
Ramification: No array bounds "sliding" is performed on subaggregates.

30.b
Reason: If sliding were performed, it would not be obvious which subaggregate would determine the bounds of the corresponding index.

31
The exception Constraint_Error is raised if any of the above checks fail.

NOTES

32 10
In an array_aggregate, positional notation may only be used with two or more expressions; a single expression in parentheses is interpreted as a parenthesized_expression. A named_array_aggregate, such as (1 => X), may be used to specify an array with a single component.

Examples

33
Examples of array aggregates with positional associations:

34
(7, 9, 5, 1, 3, 2, 4, 8, 6, 0)
Table'(5, 8, 4, 1, others => 0)  --  see 3.6

35
Examples of array aggregates with named associations:

36
(1 .. 5 => (1 .. 8 => 0.0))      --  two-dimensional
(1 .. N => new Cell)             --  N new cells, in particular for N = 0

37
Table'(2 | 4 | 10 => 1, others => 0)
Schedule'(Mon .. Fri => True,  others => False)  --  see 3.6
Schedule'(Wed | Sun  => False, others => True)
Vector'(1 => 2.5)                                --  single-component vector

38
Examples of two-dimensional array aggregates:

39
-- Three aggregates for the same value of subtype Matrix(1..2, 1..3) (see 3.6):

40
((1.1, 1.2, 1.3), (2.1, 2.2, 2.3))
(1 => (1.1, 1.2, 1.3), 2 => (2.1, 2.2, 2.3))
(1 => (1 => 1.1, 2 => 1.2, 3 => 1.3), 2 => (1 => 2.1, 2 => 2.2, 3 => 2.3))

41
Examples of aggregates as initial values:

42
A : Table := (7, 9, 5, 1, 3, 2, 4, 8, 6, 0);        -- A(1)=7, A(10)=0
B : Table := (2 | 4 | 10 => 1, others => 0);        -- B(1)=0, B(10)=1
C : constant Matrix := (1 .. 5 => (1 .. 8 => 0.0)); -- C'Last(1)=5, C'Last(2)=8

43
D : Bit_Vector(M .. N) := (M .. N => True);         -- see 3.6
E : Bit_Vector(M .. N) := (others => True);
F : String(1 .. 1) := (1 => 'F');  -- a one component aggregate: same as "F"

Extensions to Ada 83

43.a
We now allow "named with others" aggregates in all contexts where there is an applicable index constraint, effectively eliminating what was RM83-4.3.2(6).  Sliding never occurs on an aggregate with others, because its bounds come from the applicable index constraint, and therefore already match the bounds of the target.

43.b
The legality of an others choice is no longer affected by the staticness of the applicable index constraint. This substantially simplifies several rules, while being slightly more flexible for the user.  It obviates the rulings of AI-244 and AI-310, while taking advantage of the dynamic nature of the "extra values" check required by AI-309.

43.c
Named array aggregates are permitted even if the index type is descended from a formal scalar type. See 4.9 and AI-00190.

Wording Changes From Ada 83

43.d
We now separate named and positional array aggregate syntax, since, unlike other aggregates, named and positional associations cannot be mixed in array aggregates (except that an others choice is allowed in a positional array aggregate).

43.e
We have also reorganized the presentation to handle multidimensional and one-dimensional aggregates more uniformly, and to incorporate the rulings of AI-19, AI-309, etc.



[Home] [Prev] [Next] [Index]

documentation@rational.com
Copyright © 1993-1998, Rational Software Corporation.   All rights reserved.