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

3.8 Record Types

{record} {record type} A record object is a composite object consisting of named components. The value of a record object is a composite value consisting of the values of the components. {structure: See record type}


record_type_definition ::= [[abstracttagged] [limitedrecord_definition
record_definition ::= 
    end record
  | null record
component_list ::= 
      component_item {component_item}
   | {component_itemvariant_part
   |  null;
{8652/0009} {AI95-00137-01} component_item ::= component_declaration | aspect_clause representation_clause
component_declaration ::= 
   defining_identifier_list : component_definition [:= default_expression];

Name Resolution Rules

{expected type (component_declaration default_expression) [partial]} The expected type for the default_expression, if any, in a component_declaration is the type of the component. 

Legality Rules

This paragraph was deleted.{AI95-00287-01} A default_expression is not permitted if the component is of a limited type.
{AI95-00366-01} {components (of a record type) [partial]} Each component_declaration declares a component component of the record type. Besides components declared by component_declarations, the components of a record type include any components declared by discriminant_specifications of the record type declaration. [The identifiers of all components of a record type shall be distinct.] 
Proof: The identifiers of all components of a record type have to be distinct because they are all declared immediately within the same declarative region. See Section 8. 
Within a type_declaration, a name that denotes a component, protected subprogram, or entry of the type is allowed only in the following cases:
Reason: The penultimate restriction simplifies implementation, and allows the outer discriminant and the inner discriminant or bound to possibly share storage. 
Ramification: Other rules prevent such a discriminant from being an inherited one. 
Reason: The last restriction is inherited from Ada 83. The restriction is not really necessary from a language design point of view, but we did not remove it, in order to avoid unnecessary changes to existing compilers. 
Discussion: Note that a discriminant can be used to define the constraint for a component that is of an access-to-composite type. 
Reason: {AI95-00373-01} The above rules, and a similar one in 6.1 for formal parameters, are intended to allow initializations of components or parameters to occur in a (nearly) an arbitrary order — whatever order is most efficient (subject to the restrictions of 3.3.1), since one default_expression cannot depend on the value of another one. They It also prevent circularities. 
Ramification: Inherited discriminants are not allowed to be denoted, except within representation items. However, the discriminant_selector_name of the parent subtype_indication is allowed to denote a discriminant of the parent. 
If the name of the current instance of a type (see 8.6) is used to define the constraint of a component, then it shall appear as a direct_name that is the prefix of an attribute_reference whose result is of an access type, and the attribute_reference shall appear alone. 
Reason: This rule allows T'Access or T'Unchecked_Access, but disallows, for example, a range constraint (1..T'Size). Allowing things like (1..T'Size) would mean that a per-object constraint could affect the size of the object, which would be bad. 

Static Semantics

   {AI95-00318-02} {explicitly limited record} {record (explicitly limited)} If a record_type_definition includes the reserved word limited, the type is called an explicitly limited record type.
{nominal subtype (of a record component) [partial]} The component_definition of a component_declaration defines the (nominal) subtype of the component. If the reserved word aliased appears in the component_definition, then the component is aliased (see 3.10).
Ramification: {AI95-00363-01} In this case, the nominal subtype cannot be an unconstrained discriminated subtype. See 3.6.
{null record} If the component_list of a record type is defined by the reserved word null and there are no discriminants, then the record type has no components and all records of the type are null records. A record_definition of null record is equivalent to record null; end record.
Ramification: This short-hand is available both for declaring a record type and a record extension — see 3.9.1.

Dynamic Semantics

{elaboration (record_type_definition) [partial]} The elaboration of a record_type_definition creates the record type and its first subtype, and consists of the elaboration of the record_definition. {elaboration (record_definition) [partial]} The elaboration of a record_definition consists of the elaboration of its component_list, if any.
{elaboration (component_list) [partial]} The elaboration of a component_list consists of the elaboration of the component_items and variant_part, if any, in the order in which they appear. {elaboration (component_declaration) [partial]} The elaboration of a component_declaration consists of the elaboration of the component_definition.
Discussion: If the defining_identifier_list has more than one defining_identifier, we presume here that the transformation explained in 3.3.1 has already taken place. Alternatively, we could say that the component_definition is elaborated once for each defining_identifier in the list. 
 {8652/0002} {AI95-00171-01} {AI95-00230-01} {per-object expression} {per-object constraint} {entry index subtype} Within the definition of a composite type, if a component_definition or discrete_subtype_definition (see 9.5.2) includes a name that denotes a discriminant of the type, or that is an attribute_reference whose prefix denotes the current instance of the type, the expression containing the name is called a per-object expression, and the constraint or range constraint being defined is called a per-object constraint. {elaboration (component_definition) [partial]} For the elaboration of a component_definition of a component_declaration or the discrete_subtype_definition of an entry_declaration for an entry family (see 9.5.2), if the component subtype is defined by an access_definition or if the constraint or range of the subtype_indication or discrete_subtype_definition is not a per-object constraint, then the access_definition, subtype_indication, or discrete_subtype_definition is elaborated. On the other hand, if the constraint or range is a per-object constraint, then the elaboration consists of the evaluation of any included expression that is not part of a per-object expression. Each such expression is evaluated once unless it is part of a named association in a discriminant constraint, in which case it is evaluated once for each associated discriminant.
   {8652/0002} {AI95-00171-01} {Elaboration (per-object constraint) [partial]} When a per-object constraint is elaborated [(as part of creating an object)], each per-object expression of the constraint is evaluated. For other expressions, the values determined during the elaboration of the component_definition or entry_declaration are used. Any checks associated with the enclosing subtype_indication or discrete_subtype_definition are performed[, including the subtype compatibility check (see 3.2.2),] and the associated subtype is created. 
Discussion: The evaluation of other expressions that appear in component_definitions and discrete_subtype_definitions is performed when the type definition is elaborated. The evaluation of expressions that appear as default_expressions is postponed until an object is created. Expressions in representation items that appear within a composite type definition are evaluated according to the rules of the particular representation item. 
57  A component_declaration with several identifiers is equivalent to a sequence of single component_declarations, as explained in 3.3.1.
58  The default_expression of a record component is only evaluated upon the creation of a default-initialized object of the record type (presuming the object has the component, if it is in a variant_part — see 3.3.1).
59  The subtype defined by a component_definition (see 3.6) has to be a definite subtype.
60  If a record type does not have a variant_part, then the same components are present in all values of the type.
61  A record type is limited if it has the reserved word limited in its definition, or if any of its components are limited (see 7.5).
62  {predefined operations (of a record type) [partial]} The predefined operations of a record type include membership tests, qualification, and explicit conversion. If the record type is nonlimited, they also include assignment and the predefined equality operators.
63  {AI95-00287-01} A component of a record can be named with a selected_component. A value of a record can be specified with a record_aggregate, unless the record type is limited.


Examples of record type declarations: 
type Date is
      Day   : Integer range 1 .. 31;
      Month : Month_Name;
      Year  : Integer range 0 .. 4000;
   end record;
type Complex is
      Re : Real := 0.0;
      Im : Real := 0.0;
   end record;
Examples of record variables: 
Tomorrow, Yesterday : Date;
A, B, C : Complex;
-- both components of A, B, and C are implicitly initialized to zero 

Extensions to Ada 83

{extensions to Ada 83} The syntax rule for component_declaration is modified to use component_definition (instead of component_subtype_definition). The effect of this change is to allow the reserved word aliased before the component_subtype_definition.
A short-hand is provided for defining a null record type (and a null record extension), as these will be more common for abstract root types (and derived types without additional components).
The syntax rule for record_type_definition is modified to allow the reserved words tagged and limited. Tagging is new. Limitedness is now orthogonal to privateness. In Ada 83 the syntax implied that limited private was sort of more private than private. However, limitedness really has nothing to do with privateness; limitedness simply indicates the lack of assignment capabilities, and makes perfect sense for nonprivate types such as record types. 

Wording Changes from Ada 83

{8652/0009} {AI95-00137-01} The syntax rules now allow aspect_clauses representation_clauses to appear in a record_definition. This is not a language extension, because Legality Rules prevent all language-defined representation clauses from appearing there. However, an implementation-defined attribute_definition_clause could appear there. The reason for this change is to allow the rules for aspect_clauses representation_clauses and representation pragmas to be as similar as possible. 

Extensions to Ada 95

{AI95-00287-01} {extensions to Ada 95} Record components can have an anonymous access type.
{AI95-00287-01} {extensions to Ada 95} Limited components can be initialized, so long as the expression is one that allows building the object in place (such as an aggregate or function_call).

Wording Changes from Ada 95

{8652/0002} {AI95-00171-01} Corrigendum: Improved the description of the elaboration of per-object constraints.
{8652/0009} {AI95-00137-01} Corrigendum: Changed representation clauses to aspect clauses to reflect that they are used for more than just representation.
{AI95-00318-02} Defined explicitly limited record type to use in other rules. 

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