3.3 Objects and Named Numbers
[Objects are created at run time and contain a value
of a given type.
An object can be created and initialized
as part of elaborating a declaration, evaluating an allocator
or passing a parameter by copy. Prior to reclaiming the storage for an
object, it is finalized if necessary (see 7.6.1
of the following are objects:
An object is either a
constant or a variable. An object contains a value. An object is created
by an object_declaration
or by an allocator
A formal parameter is (a view of) an object. A subcomponent of an object
is an object.
a formal parameter of a subprogram, entry, or generic
a generic formal object;
a loop parameter;
the result of dereferencing an access-to-object
value (see 4.1
a component, slice, or view conversion of another
object is either a constant
object or a variable
Similarly, a view of an object is either a constant
or a variable
All views of a constant elementary object are constant. All views of
a constant composite object are constant, except for parts that are of
controlled or immutably limited types; variable views of those parts
and their subcomponents may exist. In this sense, objects of controlled
and immutably limited types are inherently mutable
A constant view of an object cannot be used to modify its value. The
terms constant and variable by themselves refer to constant and variable
views of objects.
If some part of an object has a variable view,
then the object as a whole has a variable view, and not all views of
the object are constant. That's true even if only a subcomponent has
a variable view.
A constant object is known to have no variable
views if it does not have a part that is immutably
limited, or of a controlled type, private type, or private extension.
This definition can be used in Legality Rules as
it respects privacy. It is an assume-the-worst rule, as all private types
and private extensions might have a controlled component.
The value of an object is read
when the value of any part of the object is evaluated, or when the value
of an enclosing object is evaluated.
The value of
a variable is updated
when an assignment is performed to any part
of the variable, or when an assignment is performed to an enclosing object.
Ramification: Reading and updating are
intended to include read/write references of any kind, even if they are
not associated with the evaluation of a particular construct. Consider,
for example, the expression “X.all(F)”, where X is
an access-to-array object, and F is a function. The implementation is
allowed to first evaluate “X.all” and then F. Finally,
a read is performed to get the value of the F'th component of the array.
Note that the array is not necessarily read as part of the evaluation
of “X.all”. This is important, because if F were to
free X using Unchecked_Deallocation, we want the execution of the final
read to be erroneous.
Whether a view of an object is constant or variable is determined by
the definition of the view. The following (and no others) represent variables constants
X : access constant T;
is not a constant.
a formal parameter or generic formal object
mode in out or out in
a non-discriminant component of a variable discriminant
of an access-to-variable access-to-constant
We exclude current instances of protected types
as they are protected units and the next bullet applies.
This list of bullets only applies to views of objects,
so current instances that are not objects are not considered here.
the current instance of a protected unit except
within the body of a protected function of
that protected unit, or within( or
a function declared immediately within the body
of the a protected_body),
the current instance of the enclosing
In particular, this implies that the following
are not variables:
This list of constructs that yield constant views
is not exhaustive.
At the place where a view of an object is defined,
a nominal subtype
is associated with the view. The nominal type of a view is the type of
the nominal subtype of the view.
object's actual subtype
(that is, its subtype) can be more restrictive
than the nominal subtype of the view; it always is more
if the nominal subtype is an indefinite subtype
A subtype is an indefinite subtype
if it is an unconstrained array subtype, or if it has unknown discriminants
or unconstrained discriminants without defaults (see 3.7
otherwise, the subtype is a definite
subtype [(all elementary
subtypes are definite subtypes)]. [A class-wide subtype is defined to
have unknown discriminants, and is therefore an indefinite subtype. An
indefinite subtype does not by itself provide enough information to create
an object; an additional constraint
or explicit initialization expression
is necessary (see 3.3.1
). A component cannot
have an indefinite nominal subtype.]
Glossary entry: The
nominal subtype of a view of an object is the subtype specified when
the view is defined.
A view of a composite object is known to be constrained
its nominal subtype is constrained and,
not an untagged partial view, and
it is neither a value conversion nor a qualified_expression
its nominal subtype is indefinite; or
it is part of a stand-alone constant (including
a generic formal object of mode in); or
it is part of a formal parameter of mode in;
it is a dereference of a pool-specific access type, and there is no ancestor
of its type that has a constrained partial view.
Discussion: We do not include dereferences
of general access types because they might denote stand-alone aliased
unconstrained variables. That's true even for access-to-constant types
(the denoted object does not have to be a constant).
We don't mention view conversions as there are
no mutable tagged types (discriminant defaults are allowed only if the
type is immutably limited), so all tagged view conversions are either
of an indefinite type (if it has discriminants without defaults), an
immutably limited type (if the discriminants do have defaults), or constrained
(if there are no discriminants). This matches the first three bullets
here, so all tagged view conversions are known to be constrained without
needing to mention them explicitly. Untagged view conversions only can
occur in parameter passing (as actuals to in out or out
parameters), and "known to be constrained" is not used there. There
are other cases that could have been included in this definition (view
conversions, the current instance of a type, objects of a formal discriminated
private type), but these are not relevant to the places this term is
used, so they were not included. If this term is used in additional places,
the definition should be checked to see if any of these additional cases
are relevant and appropriate wording added if necessary.
We don't need to mention the current instance of
a (sub)type, either. If a current instance of a type or subtype appears
in an aspect specification, it represents a value, so whether or not
it is known to be constrained is irrelevant (the term is only defined
for composite objects). Otherwise, the current instance of a type can
only be used in an immutably limited type, so all such instances are
known to be constrained by the third bullet.
if a subtype is a descendant of an untagged generic
formal private or derived type, and the subtype is not an unconstrained
array subtype, it is not considered indefinite and is considered to have
a constrained partial view;
if a subtype is a descendant of a formal access
type, it is not considered pool-specific.
A named number
a name for a numeric value known at compile time. It is declared by a
10 A constant cannot be the target of an
assignment operation, nor be passed as an in out or out
parameter, between its initialization and finalization, if any.
The value of a constant object cannot be changed after its initialization,
except in some cases where the object has a controlled or immutably limited
part (see 7.5
The nominal and actual subtypes of an elementary object are always the
same. For a discriminated or array object, if the nominal subtype is
constrained, then so is the actual subtype.
Extensions to Ada 83
There are additional kinds
of objects (choice parameters and entry indices of entry bodies).
The result of a function and of evaluating an
aggregate are considered (constant) objects. This is necessary to explain
the action of finalization on such things. Because a function_call
is also syntactically a name
), the result of a function_call
can be renamed, thereby allowing repeated use of the result without calling
the function again.
Wording Changes from Ada 83
This subclause now follows the subclauses on types and subtypes, to cut
down on the number of forward references.
The term nominal subtype is new. It is used
to distinguish what is known at compile time about an object's constraint,
versus what its "true" run-time constraint is.
The terms definite and indefinite (which apply
to subtypes) are new. They are used to aid in the description of generic
formal type matching, and to specify when an explicit initial value is
required in an object_declaration
We have moved the syntax for object_declaration
down into their respective subclauses, to keep the syntax close to the
description of the associated semantics.
We talk about variables and constants here,
since the discussion is not specific to object_declaration
and it seems better to have the list of the kinds of constants juxtaposed
with the kinds of objects.
We no longer talk about indirect updating due
to parameter passing. Parameter passing is handled in 6.2 and 6.4.1 in
a way that there is no need to mention it here in the definition of read
and update. Reading and updating now includes the case of evaluating
or assigning to an enclosing object.
Wording Changes from Ada 95
Clarified that the return object is the object created by a function
Extensions to Ada 2005
Added wording to allow return objects to be declared
as constants, and corrected the definition of return objects as objects.
Wording Changes from Ada 2005
We now recognize the fact that not all declared constant
objects are immutable; for those that a variable view can be constructed,
they can be changed via that view.
Added the current instance of a protected object to
the list of constant views; since the list claims to include all possibilities,
it had better include that one.
Incompatibilities With Ada 2012
the definition of “known to be constrained” so that the status
of the operand of value conversions and qualified_expressions
is always used to determine whether the property exists. As the rules
are ored together, a value conversion or qualified_expression
with a constrained nominal subtype would have always met the requirements
in Ada 2012, regardless of the operand. This change will mean that some
conversions or qualifications (mostly of variables) will no longer be
considered “known to be constrained” and therefore 'Access
and renaming of such prefixes
will now be illegal. This is necessary to meet the design goal that subsequent
execution cannot cause a renaming or 'Access to cause erroneous execution.
Extensions to Ada 2012
A value conversion of an object is an object; this
makes value conversions consistent with qualified expressions.
Wording Changes from Ada 2012
Correction: Changed from a list of constants
to a list of variables. This makes the default to be a constant, which
is the more common case, and eliminates issues caused by omissions from
the list (such as parenthesized expressions).
Added the term “known to have no variable
views” in order to have a definition that can be used in Legality
Rules without breaking privacy.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe