Ada Conformity Assessment Authority      Home Conformity Assessment   Test Suite ARGAda Standard
Annotated Ada Reference Manual (Ada 2022 Draft 35)Legal Information
Contents   Index   References   Search   Previous   Next 

4.3.3 Array Aggregates

[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

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”. For example, the requirements that others come last and stand alone are found there. 


{AI12-0306-1} array_aggregate ::= 
    positional_array_aggregate | null_array_aggregate | named_array_aggregate
{AI95-00287-01} {AI12-0212-1} {AI12-0306-1} positional_array_aggregate ::= 
    (expressionexpression {, expression})
  | (expression {, expression}, others => expression)
  | (expression {, expression}, others => <>)
  | '[' expression {, expression}[, others => expression] ']'
  | '[' expression {, expression}, others => <> ']'
{AI12-0306-1} null_array_aggregate ::= '[' ']'
{AI12-0127-1} {AI12-0212-1} named_array_aggregate ::= 
  | '[' array_component_association_list ']'
 array_component_association {, array_component_association})
{AI12-0127-1} array_component_association_list ::= 
    array_component_association {, array_component_association}
{AI95-00287-01} {AI12-0061-1} array_component_association ::= 
    discrete_choice_list => expression
  | discrete_choice_list => <>
  | iterated_component_association
{AI12-0061-1} {AI12-0212-1} iterated_component_association ::= 
    for defining_identifier in discrete_choice_list => expression
  | for iterator_specification => expression
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.
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. 
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.
 {AI12-0061-1} The defining_identifier of an iterated_component_association declares an index parameter, an object of the corresponding index type.

Name Resolution Rules

{AI95-00287-01} The expected type for an array_aggregate (that is not a subaggregate) shall be a single array type. The component type of this array type is the expected type for each array component expression of the array_aggregate.
Ramification: {AI95-00287-01} We already require a single array or record type or record extension for an aggregate. The above rule requiring a single array type (and similar ones for record and extension aggregates) resolves which kind of aggregate you have.
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

{AI12-0212-1} An array_aggregate of an n-dimensional array type shall be written as an n-dimensional array_aggregate, or as a null_array_aggregate.
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. 
{AI12-0418-1} 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 an array_aggregate the aggregate.] Each of the following contexts (and none other) defines an applicable index constraint: 
{AI95-00318-02} {AI12-0157-1} For an explicit_actual_parameter, an explicit_generic_actual_parameter, the expression of a return statement, the return expression of an expression function, 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 return object, expression function return object, object, or component is a constrained array subtype, the applicable index constraint is the constraint of the subtype;
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; 
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).
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;
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; 
Discussion: Here, the array_aggregate with others is being used within a larger aggregate. 
{AI12-0127-1} For the base_expression of a delta_aggregate, if the nominal subtype of the delta_aggregate is a constrained array subtype, the applicable index constraint is the constraint of the subtype;
{AI05-0147-1} For a parenthesized expression, the applicable index constraint is that, if any, defined for the expression;
Discussion: RM83 omitted this case, presumably as an oversight. We want to minimize situations where an expression becomes illegal if parenthesized. 
{AI05-0147-1} {AI12-0236-1} For a conditional_expression (see 4.5.7), the applicable index constraint for each dependent_expression is that, if any, defined for the conditional_expression;.
{AI12-0236-1} For a declare_expression (see 4.5.9), the applicable index constraint for the body_expression is that, if any, defined for the declare_expression.
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. 
Reason: This avoids generic contract model problems, because only mode conformance is required when matching actual subprograms with generic formal subprograms. 
{AI05-0153-3} {AI12-0061-1} {AI12-0127-1} The discrete_choice_list of an array_component_association (including an iterated_component_association) is allowed to have a discrete_choice that is a nonstatic choice_expression or that is a subtype_indication or range that defines a nonstatic or null range, only if it is the single discrete_choice of its discrete_choice_list, and either there is only one array_component_association in the enclosing array_component_association_list or the enclosing aggregate is an array_delta_aggregate[, not an array_aggregate] array_aggregate.
Discussion: We now allow a nonstatic others choice even if there are other array component expressions as well. 
Ramification: {AI12-0127-1} We allow multiple dynamic choices in array_delta_aggregates, but only one dynamic choice per association even in that case.
  {AI12-0212-1} Either all or none of the array_component_associations of an array_component_association_list shall be iterated_component_associations with an iterator_specification.
{AI05-0262-1} In a named_array_aggregate where all discrete_choices are static, 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. 
Ramification: This implies that each component must be specified exactly once. See AI83-309. 
Reason: {AI05-0262-1} This has to apply even if there is only one static discrete_choice; a single choice has to represent a contiguous range (a subtype_mark with a static predicate might represent a discontiguous set of values). If the (single) choice is a dynamic subtype, we don't need to make this check as no predicates are allowed (see 3.2.4) and thus the range has to be contiguous. 
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

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.
To be honest: {AI12-0306-1} This is true even in cases where there is no corresponding legal positional_array_aggregate.
  {AI12-0061-1} The subtype (and nominal subtype) of an index parameter is the corresponding index subtype. 

Dynamic Semantics

  {AI12-0212-1} For an array_aggregate that contains only array_component_associations that are iterated_component_associations with iterator_specifications, evaluation proceeds in two steps: 
{AI12-0212-1} {AI12-0250-1} Each iterator_specification is elaborated (in an arbitrary order) and an iteration is performed solely to determine a maximum count for the number of values produced by the iteration; all of these counts are combined to determine the overall length of the array, and ultimately the limits on the bounds of the array (defined below);
{AI12-0212-1} {AI12-0250-1} {AI12-0327-1} A second iteration is performed for each of the iterator_specifications, in the order given in the aggregate, and for each value conditionally produced by the iteration (see 5.5 and 5.5.2), the associated expression is evaluated, its value is converted to the component subtype of the array type, and used to define the value of the next component of the array starting at the low bound and proceeding sequentially toward the high bound. A check is made that the second iteration results in an array length no greater than the maximum determined by the first iteration; Constraint_Error is raised if this check fails.
To be honest: {AI12-0212-1} {AI12-0250-1} Constraint_Error should be raised no later than when the iterations exceed the maximum array length; memory that doesn't belong to the aggregate temporary should not be overwritten. 
{AI12-0212-1} The evaluation of any other an array_aggregate of a given array type proceeds in two steps: 
Any discrete_choices of this aggregate and of its subaggregates are evaluated in an arbitrary order, and converted to the corresponding index type;
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.
Ramification: Subaggregates are not separately evaluated. The conversion of the value of the component expressions to the component subtype might raise Constraint_Error.
{AI05-0005-1} We don't need to say that <> is evaluated once for each component, as <> means that each component is initialized by default. That means that the actions defined for default initialization are applied to each component individually. Initializing one component by default and copying that to the others would be an incorrect implementation in general (although it might be OK if the default initialization is known to be constant). 
  {AI95-00287-01} {AI12-0084-1} Each expression in an array_component_association defines the value for the associated component(s). For an array_component_association with <>, the associated component(s) are initialized to the Default_Component_Value of the array type if this aspect has been specified for the array type; otherwise, they are initialized by default as for a stand-alone object of the component subtype (see 3.3.1).
  {AI12-0061-1} {AI12-0212-1} During an evaluation of the expression of an iterated_component_association with a discrete_choice_list, the value of the corresponding index parameter is that of the corresponding index of the corresponding array component. During an evaluation of the expression of an iterated_component_association with an iterator_specification, the value of the loop parameter of the iterator_specification is the value produced by the iteration (as described in 5.5.2).
Ramification: Taken together with the preceding rule that “The array component expressions of the aggregate are evaluated in an arbitrary order”, this implies that an index parameter of an iterated_component_association can take on its values in an arbitrary order. This is different from other constructs, such as a loop_statement. In contrast, a loop parameter of an iterated_component_association takes its values in the order defined by the iteration, the same as a loop_statement.
The bounds of the index range of an array_aggregate [(including a subaggregate)] are determined as follows: 
For an array_aggregate with an others choice, the bounds are those of the corresponding index range from the applicable index constraint;
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)];
{AI12-0212-1} {AI12-0306-1} For a null_array_aggregate, bounds for each dimension are determined as for a positional_array_aggregate without an others choice that has no expressions for each dimension;
Reason: We need a separate rule to describe what happens for a multidimensional null_array_aggregate; we could've combined the single-dimension case with the positional_array_aggregate rule. 
{AI12-0212-1} {AI12-0250-1} For a named_array_aggregate containing only iterated_component_associations with an iterator_specification, the lower bound is determined as for a positional_array_aggregate without an others choice, and the upper bound is determined from the lower bound and the total number of values produced by the second set of iterations;
{AI12-0212-1} For any other 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.
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. 
For an array_aggregate, a check is made that the index range defined by its bounds is compatible with the corresponding index subtype. 
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. 
Ramification: The definition of compatibility handles the special case of a null range, which is always compatible with a subtype. See AI83-00313. 
{AI05-0037-1} For an array_aggregate with an others choice, a check is made that no expression or <> is specified for an index value outside the bounds determined by the applicable index constraint. 
Discussion: RM83 omitted this case, apparently through an oversight. AI83-00309 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. 
For a multidimensional array_aggregate, a check is made that all subaggregates that correspond to the same index have the same bounds. 
Ramification: No array bounds “sliding” is performed on subaggregates. 
Reason: If sliding were performed, it would not be obvious which subaggregate would determine the bounds of the corresponding index. 
The exception Constraint_Error is raised if any of the above checks fail. 

Implementation Permissions

{AI12-0212-1} {AI12-0250-1} When evaluating iterated_component_associations for an array_aggregate that contains only iterated_component_associations with iterator_specifications, the first step of evaluating an iterated_component_association can be omitted if the implementation can determine the maximum number of values by some other means.
Discussion: For instance, if the type of the aggregate is constrained, the implementation can (but does not have to) calculate the expected length from the constraint.
NOTE 1   {AI05-0004-1} {AI12-0306-1} {AI12-0440-1} In an array_aggregate delimited by parentheses, positional notation can may only be used with two or more expressions; a single expression in parentheses is interpreted as a parenthesized expression. An array_aggregate delimited by square brackets A named_array_aggregate, such as (1 => X), can may be used to specify an array with a single component.
NOTE 2   {AI12-0061-1} An index parameter is a constant object (see 3.3).


Examples of array aggregates with positional associations: 
(7, 9, 5, 1, 3, 2, 4, 8, 6, 0)
Table'(5, 8, 4, 1, others => 0)  -- see 3.6 
Examples of array aggregates with named associations: 
{AI12-0306-1} (1 .. 5 => (1 .. 8 => 0.0))      -- two-dimensional
[(1 .. N => new Cell])             -- N new cells, in particular for N = 0
{AI12-0306-1} 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
Examples of two-dimensional array aggregates: 
-- Three aggregates for the same value of subtype Matrix(1..2,1..3) (see 3.6):
{AI12-0306-1} ((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)])
Examples of aggregates as initial values: 
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
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"
{AI12-0061-1} G : constant Matrix :=
    (for I in 1 .. 4 =>
       (for J in 1 .. 4 =>
          (if I=J then 1.0 else 0.0))); -- Identity matrix
{AI12-0312-1} Empty_Matrix : constant Matrix := []; -- A matrix without elements
{AI95-00433-01} Example of an array aggregate with defaulted others choice and with an applicable index constraint provided by an enclosing record aggregate:
{AI12-0178-1} Buffer'(Size => 50, Pos => 1, Value => String'('x', others => <>)) -- see 3.7

Incompatibilities With Ada 83

In Ada 95, no applicable index constraint is defined for a parameter in a call to a generic formal subprogram; thus, some aggregates that are legal in Ada 83 are illegal in Ada 95. For example: 
subtype S3 is String (1 .. 3);
   with function F (The_S3 : in S3) return Integer;
package Gp is
   I : constant Integer := F ((1 => '!', others => '?'));
       -- The aggregate is legal in Ada 83, illegal in Ada 95.
end Gp;
This change eliminates generic contract model problems. 

Extensions to Ada 83

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.
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 AI83-00244 and AI83-00310, while taking advantage of the dynamic nature of the "extra values" check required by AI83-00309.
Named array aggregates are permitted even if the index type is descended from a formal scalar type. See 4.9 and AI83-00190. 

Wording Changes from Ada 83

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).
We have also reorganized the presentation to handle multidimensional and one-dimensional aggregates more uniformly, and to incorporate the rulings of AI83-00019, AI83-00309, etc. 

Extensions to Ada 95

{AI95-00287-01} <> can be used in place of an expression in an array_aggregate, default-initializing the component. 

Wording Changes from Ada 95

{AI95-00287-01} Limited array_aggregates are allowed (since all kinds of aggregates can now be limited, see 4.3).
{AI95-00318-02} Fixed aggregates to use the subtype of the return object of a function, rather than the result subtype, because they can be different for an extended_return_statement, and we want to use the subtype that's explicitly in the code at the point of the expression.

Inconsistencies With Ada 2005

{AI05-0037-1} Correction: Fixed so the check for components outside of the array applies to both expressions and <>s. As <> was a new feature in Ada 2005, there should be little existing code that depends on a <> component that is specified outside of the array (and that is nonsense anyway, that a compiler is likely to detect even without an explicit language rule disallowing it). 

Wording Changes from Ada 2005

{AI05-0147-1} Added a definition of the applicable index constraint for conditional_expressions (which are new). 

Inconsistencies With Ada 2012

{AI05-0084-1} Corrigendum: Fixed so that the Default_Component_Value (if any) is used to initialize components specified with <>. This is what users would expect, and all Ada 2012 implementation known at the time of this writing initialize with the Default_Component_Value, so it is unlikely that anyone will be affected by this inconsistency. 

Extensions to Ada 2012

{AI12-0061-1} {AI12-0212-1} {AI12-0250-1} The iterated_component_association is new (more than 25 years after it was originally proposed). It has been extended to allow container iterators as well as the basic index iterators.
{AI12-0212-1} An array_aggregate can be surrounded by brackets rather than parentheses. This allows consistent writing of zero- and one-component positional array aggregates, and is consistent with the syntax for writing container aggregates.
{AI12-0212-1} {AI12-0306-1} A null_array_aggregate is new. 

Wording Changes from Ada 2012

{AI05-0157-1} Corrigendum: Added expression functions to the contexts that provide an applicable index constraint, because expression functions are handled separately in static semantics and legality rules.
{AI12-0127-1} Made syntax and wording changes for delta_aggregates.
{AI12-0236-1} Added a definition of the applicable index constraint for declare_expressions (which are new). This allows others in array aggregates inside of declare_expressions.

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe