Ada Resource Association
News and resources for the Ada programming language
Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

4.3.2 Extension Aggregates

[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

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. 


extension_aggregate ::= 
    (ancestor_part with record_component_association_list)
ancestor_part ::= expression | subtype_mark

Name Resolution Rules

{AI95-00287-01} {expected type (extension_aggregate) [partial]} The expected type for an extension_aggregate shall be a single nonlimited type that is a record extension. {expected type (extension_aggregate ancestor expression) [partial]} If the ancestor_part is an expression, it is expected to be of any nonlimited tagged type. 
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

{AI95-00306-01} If the ancestor_part is a subtype_mark, it shall denote a specific tagged subtype. If the ancestor_part is an expression, it shall not be dynamically tagged. 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). 
Reason: {AI95-00306-01} 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.

Static Semantics

{needed component (extension_aggregate record_component_association_list)} 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

{evaluation (extension_aggregate) [partial]} 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.
{Discriminant_Check [partial]} {check, language-defined (Discriminant_Check)} 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 (raised by failure of run-time check)} Constraint_Error is raised if this check fails. 
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. 
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.
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 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

{extensions to Ada 83} The extension aggregate syntax is new. 

Incompatibilities With Ada 95

{AI95-00306-01} {incompatibilities with Ada 95} Amendment Correction: 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

{AI95-00287-01} Limited extension_aggregates are allowed (since all kinds of aggregates can now be limited, see 4.3).

Contents   Index   References   Search   Previous   Next 
Ada-Europe Sponsored by Ada-Europe