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
3
4/2
5
6
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
7.a/3
7.b
Name Resolution Rules
8/2
8.a
9
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 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.
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
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.
11.b/3
{
AI05-0005-1}
For a derived type (including type extensions),
the order of declaration is defined in 3.4,
“Derived Types and Classes”. In
particular, all discriminants come first, regardless of whether they
are defined for the parent type or are newly added to the derived type.
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/3
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.
15.b/3
16/3
16.a/2
Ramification: {
AI95-00287-01}
These rules apply to an association with an
others choice
with an expression. An others choice with a <> can match
zero components or several components with different types.
16.b/2
Reason: {
AI95-00287-01}
Without these rules, there would be no way to know what was the expected
type for the
expression
of the association.
Note that some of the rules
do not apply to <> associations, as we do not need to resolve anything.
We allow others => <> to match no components as this
is similar to array aggregates. That means that (others =>
<>) always represents a default-initialized record or array value.
16.c
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.
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/3
{
AI05-0220-1}
The If the components
of a variant_part
are needed, then the value of a discriminant that governs
a the
variant_part
P shall be given by a static expression
,
unless P is nested within a variant
V that is not selected by the discriminant value governing the
variant_part
enclosing V.
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.
17.1/2
17.b/2
Reason: A discriminant
must always have a defined value, but <> means uninitialized for
a discrete type unless the component has a default value.
Dynamic Semantics
18
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.
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.
19.a
Ramification: The conversion in the first
rule might raise Constraint_Error.
19.b
Discussion: This check in the first rule
presumably happened as part of the dependent compatibility check in Ada
83.
19.1/2
20
20.a/3
Ramification: {
AI05-0005-1}
We don't need similar language for <>, as
we're considering the value of <> for each individual component.
Each component has its own default expression or its own default initialization
(they can be different for each component; the components even could
have different types), and each one has to be evaluated. So there is
no need to repeat that.
21
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/2
{
AI95-00287-01}
Examples Example of component associations 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
29.1/2
(Value => 0, Succ|Pred => <>) -- see 3.10.1
29.2/2
-- Succ and Pred will be set to null
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 (AI83-00189,
AI83-00244, and AI83-00309). In particular, Ada 83 did not explicitly
disallow extra values in a record aggregate. Now we do.
Extensions to Ada 95
31.c/2
Wording Changes from Ada 95
31.d/2
Incompatibilities With Ada 2005
31.e/3
{
AI05-0220-1}
Correction: Corrected
wording so that the rule for discriminants governing variant_parts
was not effectively circular. The change makes a few aggregates
where a non-static discriminant governs an empty variant_part
illegal. However, most Ada implementations already enforce some version
of the new rule and already reject these aggregates.
So it is unlikely that any incompatibility will be noticed in practice.
Extensions to Ada 2005
31.f/3
{
AI05-0016-1}
Correction: Fixed the
wording so that others => <> can be used in place of
null record. This is needed to avoid a generic contract issue
for generic bodies: we do not want to have to assume the worst to disallow
others => <> if the record type might be a null
record.
31.g/3
{
AI05-0199-1}
Correction: We now allow multiple components
with anonymous access types to be specified with a single component association.
This is to be consistent with the capabilities of a named access type.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe