3.8 Record Types
1
{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}
Syntax
2
record_type_definition ::= [[
abstract]
tagged] [
limited]
record_definition
3
record_definition ::=
record
component_list
end record
|
null record
4
component_list ::=
component_item {
component_item}
| {
component_item}
variant_part
|
null;
5/1
6
component_declaration ::=
defining_identifier_list :
component_definition [:=
default_expression];
Name Resolution Rules
7
{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
8/2
This paragraph was
deleted.{
AI95-00287-01}
A default_expression
is not permitted if the component is of a limited type.
9/2
{
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.]
9.a
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.
10
Within a type_declaration,
a name that denotes a component, protected
subprogram, or entry of the type is allowed only in the following cases:
11
- A name
that denotes any component, protected subprogram, or entry is allowed
within a representation item that occurs within the declaration of the
composite type.
12
- 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.{discriminant
(use in a record definition)}
12.a
Reason: The penultimate restriction simplifies
implementation, and allows the outer discriminant and the inner discriminant
or bound to possibly share storage.
12.b
Ramification: Other rules prevent such
a discriminant from being an inherited one.
12.c
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.
12.d
Discussion: Note that a discriminant
can be used to define the constraint for a component that is of an access-to-composite
type.
12.e/2
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.
12.f
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.
13
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.
13.a
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
13.1/2
{
AI95-00318-02}
{explicitly limited
record} {record
(explicitly limited)} If a record_type_declaration
includes the reserved word limited, the type is called an explicitly
limited record type.
14
{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).
14.a/2
This paragraph
was deleted.Ramification: {
AI95-00363-01}
In this case, the nominal subtype cannot be an
unconstrained discriminated subtype. See 3.6.
15
{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.
15.a
Ramification: This short-hand is available
both for declaring a record type and a record extension — see
3.9.1.
Dynamic Semantics
16
{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.
17
{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.
17.a
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.
18/2
{
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.
18.1/1
{
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.
18.a
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.
19
57 A
component_declaration
with several identifiers is equivalent to a sequence of single
component_declarations,
as explained in
3.3.1.
20
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).
21
59 The subtype defined by a
component_definition
(see
3.6) has to be a definite subtype.
22
60 If a record type does not have a variant_part,
then the same components are present in all values of the type.
23
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).
24
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.
25/2
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
26
Examples of record
type declarations:
27
type Date is
record
Day : Integer range 1 .. 31;
Month : Month_Name;
Year : Integer range 0 .. 4000;
end record;
28
type Complex is
record
Re : Real := 0.0;
Im : Real := 0.0;
end record;
29
Examples of record
variables:
30
Tomorrow, Yesterday : Date;
A, B, C : Complex;
31
-- both components of A, B, and C are implicitly initialized to zero
Extensions to Ada 83
31.a
{
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.
31.b
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).
31.c
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
31.d/1
{
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
31.e/2
{
AI95-00287-01}
{extensions to Ada 95} Record
components can have an anonymous access type.
31.f/2
{
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
31.g/2
{
8652/0002}
{
AI95-00171-01}
Corrigendum: Improved the description of
the elaboration of per-object constraints.
31.h/2
{
8652/0009}
{
AI95-00137-01}
Corrigendum: Changed representation clauses
to aspect clauses to reflect that they are used for more than just representation.
31.i/2
{
AI95-00318-02}
Defined explicitly limited record type to
use in other rules.