An assignment statement replaces the current value of a variable with a new value specified by an expression. The named variable and the right-hand side expression must be of the same type; this type must not be a limited type.
assignment_statement ::= variable_name := expression;
For the execution of an assignment statement, the variable name and the expression are first evaluated, in some order that is not defined by the language. A check is then made that the value of the expression belongs to the subtype of the variable, except in the case of a variable that is an array (the assignment then involves a subtype conversion as described in section 5.2.1). Finally, the value of the expression becomes the new value of the variable.
The exception CONSTRAINT_ERROR is raised if the above-mentioned subtype check fails; in such a case the current value of the variable is left unchanged. If the variable is a subcomponent that depends on discriminants of an unconstrained record variable, then the execution of the assignment is erroneous if the value of any of these discriminants is changed by this execution.
VALUE := MAX_VALUE - 1; SHADE := BLUE; NEXT_FRAME(F)(M, N) := 2.5; -- see 4.1.1 U := DOT_PRODUCT(V, W); -- see 6.5 WRITER := (STATUS => OPEN, UNIT => PRINTER, LINE_COUNT => 60); -- see 3.7.3 NEXT_CAR.all := (72074, null); -- see 3.8.1
Examples of constraint checks:
I, J : INTEGER range 1 .. 10; K : INTEGER range 1 .. 20; ... I := J; -- identical ranges K := J; -- compatible ranges J := K; -- will raise the exception CONSTRAINT_ERROR if K > 10
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, created by allocators, are always constrained (see 4.8); however, subcomponents of such objects may be unconstrained.
If the right-hand side expression is either a numeric literal or named number, or an attribute that yields a result of type universal_integer or universal_real, then an implicit type conversion is performed, as described in section 4.6.
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 section 8.7 for the context of overload resolution).
References: access type, allocator, array, array assignment, component, and 3.7, constraint_error exception, designate, discriminant, erroneous, evaluation, expression, function call, implicit type conversion, name, numeric literal, object, overloading, and 8.7, slice, subcomponent, subtype, subtype conversion, type, universal_integer type, universal_real type, variable.
Rationale references: 3.8 Assignment Statements - The Ada Model of Time
Style Guide references: 2.1.3 Alignment of Operators, 5.6.2 Slices
If the variable of an assignment statement is an array variable (including a slice variable), the value of the expression is implicitly converted to the subtype of the array variable; the result of this subtype conversion becomes the new value of the array variable.
This means that the new value of each component of the array variable is specified by the matching component in the array value obtained by evaluation of the expression (see 4.5.2 for the definition of matching components). The subtype conversion checks that for each component of the array variable there is a matching component in the array value, and vice versa. The exception CONSTRAINT_ERROR is raised if this check fails; in such a case the value of each component of the array variable is left unchanged.
A : STRING(1 .. 31); B : STRING(3 .. 33); ... A := B; -- same number of components A(1 .. 9) := "tar sauce"; A(4 .. 12) := A(1 .. 9); -- A(1 .. 12) = "tartar sauce"
Array assignment is defined even in the case of overlapping slices, because the expression on the right-hand side is evaluated before performing any component assignment. In the above example, an implementation yielding A(1 .. 12) = "tartartartar" would be incorrect.
The implicit subtype conversion described above for assignment to an array variable is performed only for the value of the right-hand side expression as a whole; it is not performed for subcomponents that are array values.
References: array, assignment, constraint_error exception, matching array components, slice, subtype conversion, type, variable.
Address any questions or comments to firstname.lastname@example.org.