4.3.2 Extension Aggregates
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
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.
Name Resolution Rules
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.
This rule is additive with the rule given in 4.3.
That means the 4.3 rule must be satisfied even
though it is always syntactically possible to tell that something is
an extension aggregate rather than another kind of aggregate. Specifically,
that means that an extension aggregate is ambiguous if the context is
overloaded on array and/or untagged record types, even though those are
never legal contexts for an extension aggregate. Thus, this rule acts
more like a Legality Rules than a Name Resolution Rules.
The expression cannot be dynamically tagged to
prevent implicit "truncation" of a dynamically-tagged value
to the specific ancestor type. This is similar to the rules in 3.9.2.
a call to a function with
an unconstrained result subtype; nor
a parenthesized or qualified
expression whose operand would violate this rule; nor
This restriction simplifies implementation, because
it ensures that either the caller or the callee knows the size to allocate
for the aggregate. Without this restriction, information from both caller
and callee would have to be combined to determine the appropriate size.
The (F(...) with null record) case is exempt from
this rule, because such extension aggregates are created internally for
inherited functions returning null-extension types — we can't very
well make those illegal. Moreover, we don't need the rule for null extensions,
as the result can simply use the space returned by the function call.
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.
The check needs to be made any time that the ancestor
is constrained; the source of the discriminants or the constraints is
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
Examples of extension
aggregates (for types defined in 3.9.1):
Painted_Point'(Point with Red)
(Point'(P) with Paint => Black)
(Expression with Left => 1.2, Right => 3.4)
Addition'(Binop with null record)
-- presuming Binop is of type Binary_Operation
Extensions to Ada 83
The extension aggregate
syntax is new.
Incompatibilities With Ada 95
Eliminated implicit “truncation” of a dynamically tagged
value when it is used as an ancestor expression.
If an aggregate
includes such an expression,
it is illegal in Ada 2005. Such aggregates
are thought to be rare; the problem can be fixed with a type conversion
to the appropriate specific type if it occurs.
Wording Changes from Ada 95
Inconsistencies With Ada 2005
Correction: An extension_aggregate
with an ancestor_part
whose discriminants are constrained and inherited might now raise Constraint_Error
if the aggregate's
type is constrained, while it was OK in Ada 2005. In almost all cases,
this will make no difference as the constraint will be checked by the
immediately following use of the aggregate,
but it is possible to compare such an aggregate for equality; in this
case, no exception would be raised by Ada 2005, while Ada 2012 will raise
Constraint_Error. This should be very rare, and having the possibility
means that the representation of the aggregate type has to be able to
support unconstrained values of the type, even if the first subtype is
constrained and no such objects can be created any other way.
Incompatibilities With Ada 2005
Correction: A limited
unconstrained ancestor expression that is a function call is now illegal
unless the extension part is null. Such aggregates
were first introduced in Ada 2005 and are very complex to implement as
they must be built-in-place with an unknown size; as such, it is unlikely
that they are implemented correctly in existing compilers and thus not
often used in existing code.
Correction: An ancestor_part
that is a subtype with unknown discriminants is now explicitly illegal.
Such a subtype should not be used to declare an object, and the ancestor_part
acts like an object. The Ada 95 rules did not disallow such cases, so
it is possible that code exists that uses such an ancestor, but this
should be rare.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe