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.
Syntax
Name Resolution Rules
Legality Rules
Proof: {
AI05-0299-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.
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.
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
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
{
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.
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.
64 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).
66 If a record type does not have a
variant_part,
then the same components are present in all values of the type.
67 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).
68
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.
Examples
Examples of record
type declarations:
type Date is
record
Day : Integer range 1 .. 31;
Month : Month_Name;
Year : Integer range 0 .. 4000;
end record;
type Complex is
record
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
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
Extensions to Ada 95
{
AI95-00287-01}
Record components can have an anonymous access type.
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
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe