4.5.3 Binary Adding Operators
Static Semantics
The
binary adding operators + (addition) and – (subtraction) are predefined
for every specific numeric type
T with their conventional meaning.
They have the following specifications:
function "+"(Left, Right : T) return T
function "-"(Left, Right : T) return T
The
concatenation operators & are predefined for every nonlimited, one-dimensional
array type
T with component type
C. They have the following
specifications:
function "&"(Left : T; Right : T) return T
function "&"(Left : T; Right : C) return T
function "&"(Left : C; Right : T) return T
function "&"(Left : C; Right : C) return T
Dynamic Semantics
For
the evaluation of a concatenation with result type
T, if both
operands are of type
T, the result of the concatenation is a one-dimensional
array whose length is the sum of the lengths of its operands, and whose
components comprise the components of the left operand followed by the
components of the right operand. If the left operand is a null array,
the result of the concatenation is the right operand. Otherwise, the
lower bound of the result is determined as follows:
If the ultimate ancestor of the array type was
defined by a
constrained_array_definition,
then the lower bound of the result is that of the index subtype;
Reason: This rule avoids Constraint_Error
when using concatenation on an array type whose first subtype is constrained.
If the ultimate ancestor of the array type was
defined by an
unconstrained_array_definition,
then the lower bound of the result is that of the left operand.
[The upper bound is determined by the lower bound
and the length.]
A check is made
that the upper bound of the result of the concatenation belongs to the
range of the index subtype, unless the result is a null array.
Constraint_Error
is raised if this check fails.
If either operand is of the component type
C,
the result of the concatenation is given by the above rules, using in
place of such an operand an array having this operand as its only component
(converted to the component subtype) and having the lower bound of the
index subtype of the array type as its lower bound.
Ramification: The conversion might raise
Constraint_Error. The conversion provides “sliding” for the
component in the case of an array-of-arrays, consistent with the normal
Ada 95 rules that allow sliding during parameter passing.
The result of a concatenation
is defined in terms of an assignment to an anonymous object, as for any
function call (see
6.5).
Ramification: This implies that value
adjustment is performed as appropriate — see
7.6.
We don't bother saying this for other predefined operators, even though
they are all function calls, because this is the only one where it matters.
It is the only one that can return a value having controlled parts.
NOTE As for all predefined operators
on modular types, the binary adding operators + and – on modular
types include a final reduction modulo the modulus if the result is outside
the base range of the type.
Implementation Note: A full "modulus"
operation need not be performed after addition or subtraction of modular
types. For binary moduli, a simple mask is sufficient. For nonbinary
moduli, a check after addition to see if the value is greater than the
high bound of the base range can be followed by a conditional subtraction
of the modulus. Conversely, a check after subtraction to see if a "borrow"
was performed can be followed by a conditional addition of the modulus.
Examples
Examples of expressions
involving binary adding operators:
Z + 0.1 -- Z has to be of a real type
"A" & "BCD" -- concatenation of two string literals
'A' & "BCD" -- concatenation of a character literal and a string literal
'A' & 'A' -- concatenation of two character literals
Inconsistencies With Ada 83
The lower bound of the result
of concatenation, for a type whose first subtype is constrained, is now
that of the index subtype. This is inconsistent with Ada 83, but generally
only for Ada 83 programs that raise Constraint_Error. For example, the
concatenation operator in
X : array(1..10) of Integer;
begin
X := X(6..10) & X(1..5);
would raise Constraint_Error in Ada 83 (because
the bounds of the result of the concatenation would be 6..15, which is
outside of 1..10), but would succeed and swap the halves of X (as expected)
in Ada 95.
Extensions to Ada 83
Concatenation is now useful
for array types whose first subtype is constrained. When the result type
of a concatenation is such an array type, Constraint_Error is avoided
by effectively first sliding the left operand (if nonnull) so that its
lower bound is that of the index subtype.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe