5.2 Assignment Statements
1
Syntax
2
3
The execution of an
assignment_statement
includes the evaluation of the
expression
and the
assignment of the value of the
expression
into the
target.
[An assignment
operation (as opposed to an
assignment_statement)
is performed in other contexts as well, including object initialization
and by-copy parameter passing.]
The
target of an assignment operation is the view of the object to
which a value is being assigned; the target of an
assignment_statement
is the variable denoted by the
variable_name.
3.a
Discussion: Don't confuse this notion
of the “target” of an assignment with the notion of the “target
object” of an entry call or requeue.
3.b
Don't confuse the term “assignment operation”
with the
assignment_statement.
The assignment operation is just one part of the execution of an
assignment_statement.
The assignment operation is also a part of the execution of various other
constructs; see
7.6.1, “
Completion
and Finalization” for a complete list. Note that when we say,
“such-and-such is assigned to so-and-so”, we mean that the
assignment operation is being applied, and that so-and-so is the target
of the assignment operation.
Name Resolution Rules
4/2
4.a
4.b
type P1 is access R1;
type P2 is access R2;
4.c
function F return P1;
function F return P2;
4.d
X : R1;
begin
F.all := X; -- Right hand side helps resolve left hand side
Legality Rules
5/2
{
AI95-00287-01}
The target [denoted by the
variable_name]
shall be a variable
of a nonlimited type.
6
If the target is of a tagged class-wide type
T'Class,
then the
expression
shall either be dynamically tagged, or of type
T and tag-indeterminate
(see
3.9.2).
6.a
Reason: This is consistent with the general
rule that a single dispatching operation shall not have both dynamically
tagged and statically tagged operands. Note that for an object initialization
(as opposed to the
assignment_statement),
a statically tagged initialization expression is permitted, since there
is no chance for confusion (or Tag_Check failure). Also, in an object
initialization, tag-indeterminate expressions of any type covered by
T'Class would be allowed, but with an
assignment_statement,
that might not work if the tag of the target was for a type that didn't
have one of the dispatching operations in the tag-indeterminate expression.
Dynamic Semantics
7
7.a
Ramification: Other rules of the language
may require that the bounds of the variable be determined prior to evaluating
the
expression,
but that does not necessarily require evaluation of the
variable_name,
as pointed out by the ACID.
8
When the type of the
target is class-wide:
9
If the
expression
is tag-indeterminate (see
3.9.2), then the
controlling tag value for the
expression
is the tag of the target;
9.a
10
Otherwise
[(the
expression
is dynamically tagged)], a check is made that the tag of the value of
the
expression
is the same as that of the target; if this check fails, Constraint_Error
is raised.
11
The value of the
expression
is converted to the subtype of the target. [The conversion might raise
an exception (see
4.6).]
11.a
Ramification: 4.6,
“
Type Conversions” defines what
actions and checks are associated with subtype conversion. For non-array
subtypes, it is just a constraint check presuming the types match. For
array subtypes, it checks the lengths and slides if the target is constrained.
“Sliding” means the array doesn't have to have the same bounds,
so long as it is the same length.
12
In cases involving controlled types, the target is
finalized, and an anonymous object might be used as an intermediate in
the assignment, as described in
7.6.1, “
Completion
and Finalization”.
In
any case, the converted value of the
expression
is then
assigned to the target, which consists of the following
two steps:
12.a
To be honest: 7.6.1
actually says that finalization happens always, but unless controlled
types are involved, this finalization during an
assignment_statement
does nothing.
13
The value of the target becomes the converted value.
14
If any part of the target is controlled, its value
is adjusted as explained in clause
7.6.
14.a
Ramification: If any parts of the object
are controlled, abort is deferred during the assignment operation itself,
but not during the rest of the execution of an
assignment_statement.
15
2 The tag of an object never changes; in
particular, an
assignment_statement
does not change the tag of the target.
16/2
This paragraph was
deleted.3 {
AI95-00363-01}
The values of the discriminants of an object designated
by an access value cannot be changed (not even by assigning a complete
value to the object itself) since such objects are always constrained;
however, subcomponents of such objects may be unconstrained.
16.a
Ramification: The implicit subtype conversion
described above for
assignment_statements
is performed only for the value of the right-hand side expression as
a whole; it is not performed for subcomponents of the value.
16.b
The determination of the type of the variable
of an
assignment_statement
may require consideration of the expression if the variable name can
be interpreted as the name of a variable designated by the access value
returned by a function call, and similarly, as a component or slice of
such a variable (see
8.6, “
The
Context of Overload Resolution”).
Examples
17
Examples of assignment
statements:
18
Value := Max_Value - 1;
Shade := Blue;
19
Next_Frame(F)(M, N) := 2.5; --
see 4.1.1
U := Dot_Product(V, W); --
see 6.3
20
Writer := (Status => Open, Unit => Printer, Line_Count => 60); --
see 3.8.1
Next_Car.
all := (72074,
null); --
see 3.10.1
21
Examples involving
scalar subtype conversions:
22
I, J : Integer range 1 .. 10 := 5;
K : Integer range 1 .. 20 := 15;
...
23
I := J; -- identical ranges
K := J; -- compatible ranges
J := K; -- will raise Constraint_Error if K > 10
24
Examples involving
array subtype conversions:
25
A : String(1 .. 31);
B : String(3 .. 33);
...
26
A := B; -- same number of components
27
A(1 .. 9) := "tar sauce";
A(4 .. 12) := A(1 .. 9); -- A(1 .. 12) = "tartar sauce"
28
4
Notes on the examples: Assignment_statements
are allowed even in the case of overlapping slices of the same array,
because the
variable_name
and
expression
are both evaluated before copying the value into the variable. In the
above example, an implementation yielding A(1 .. 12) = "tartartartar"
would be incorrect.
Extensions to Ada 83
28.a
Wording Changes from Ada 83
28.b
The special case of array assignment is subsumed
by the concept of a subtype conversion, which is applied for all kinds
of types, not just arrays. For arrays it provides “sliding”.
For numeric types it provides conversion of a value of a universal type
to the specific type of the target. For other types, it generally has
no run-time effect, other than a constraint check.
28.c
We now cover in a general way in
3.7.2
the erroneous execution possible due to changing the value of a discriminant
when the variable in an
assignment_statement
is a subcomponent that depends on discriminants.
Incompatibilities With Ada 95
28.d/2
{
AI95-00287-01}
The change of the limited check
from a resolution rule to a legality rule is not quite upward compatible.
For example.
28.e
type AccNonLim is access NonLim;
function Foo (Arg : in Integer) return AccNonLim;
type AccLim is access Lim;
function Foo (Arg : in Integer) return AccLim;
Foo(2).all := Foo(1).all;.
28.f
where NonLim is a nonlimited
type and Lim is a limited type. The assignment is legal in Ada 95 (only
the first Foo would be considered), and is ambiguous in Ada 2005. We
made the change because we want limited types to be as similar to nonlimited
types as possible. Limited expressions are now allowed in all other contexts
(with a similar incompatibility), and it would be odd if assignments
had different resolution rules (which would eliminate ambiguities in
some cases). Moreover, examples like this one are rare, as they depend
on assigning into overloaded function calls.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe