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

3.8 Record Types

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.


record_type_definition ::= [[abstracttagged] [limitedrecord_definition
{AI12-0213-1} record_definition ::= 
    end record [record_identifier]
  | null record
component_list ::= 
      component_item {component_item}
   | {component_itemvariant_part
   |  null;
{8652/0009} {AI95-00137-01} component_item ::= component_declaration | aspect_clause
{AI05-0183-1} component_declaration ::= 
   defining_identifier_list : component_definition [:= default_expression]
{AI12-0213-1} If a record_identifier appears at the end of the record_definition, it shall repeat the defining_identifier of the enclosing full_type_declaration.

Name Resolution Rules

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}
{AI95-00366-01} Each component_declaration declares a 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: {AI05-0299-1} {AI12-0449-1} 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 Clause 8 Clause 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:
{AI05-0004-1} {AI05-0295-1} A name that denotes any component, protected subprogram, or entry is allowed within an aspect_specification, an operational item, or a representation item that occurs within the declaration of the composite type.
{AI05-0264-1} A name that denotes a noninherited discriminant is allowed within the declaration of the type, but not within the discriminant_part. If the discriminant is used to define the constraint of a component, the bounds of an entry family, or the constraint of the parent subtype in a derived_type_definition, then its name shall appear alone as a direct_name (not as part of a larger expression or expanded name). A discriminant shall not be used to define the constraint of a scalar component.
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) 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 also prevent circularities.
Ramification: {AI05-0295-1} Inherited discriminants are not allowed to be denoted, except within aspect_specifications and 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} {AI05-0004-1} If a record_type_definition includes the reserved word limited, the type is called an explicitly limited record type.
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).
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: {AI12-0426-1} This shorthand short-hand is available both for declaring a record type and a record extension — see 3.9.1

Dynamic Semantics

The elaboration of a record_type_definition creates the record type and its first subtype, and consists of the elaboration of the record_definition. The elaboration of a record_definition consists of the elaboration of its component_list, if any.
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. 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} 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 being defined is called a per-object constraint. 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} 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. 
NOTE 1   A component_declaration with several identifiers is equivalent to a sequence of single component_declarations, as explained in 3.3.1.
NOTE 2   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).
NOTE 3   The subtype defined by a component_definition (see 3.6) has to be a definite subtype.
NOTE 4   If a record type does not have a variant_part, then the same components are present in all values of the type.
NOTE 5   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).
NOTE 6   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.
NOTE 7   {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.


Examples of record type declarations: 
{AI12-0430-1} type Date is
      Day   : Integer range 1 .. 31;
      Month : Month_Name;                  -- see 3.5.1
      Year  : Integer range 0 .. 4000;
   end record;
{AI12-0213-1} type Complex is
      Re : Real := 0.0;
      Im : Real := 0.0;
   end record Complex;
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

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 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 and representation pragmas to be as similar as possible. 

Extensions to Ada 95

{AI95-00287-01} Record components can have an anonymous access type.
{AI95-00287-01} 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.

Extensions to Ada 2005

{AI05-0183-1} An optional aspect_specification can be used in a component_declaration. This is described in 13.1.1

Extensions to Ada 2012

{AI12-0213-1} The record_identifier following end record is new. 

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