Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

4.5 Operators and Expression Evaluation

[{precedence of operators} {operator precedence} The language defines the following six categories of operators (given in order of increasing precedence). The corresponding operator_symbols, and only those, can be used as designators in declarations of functions for user-defined operators. See 6.6, “Overloading of Operators”.] 


logical_operator ::=   and | or  | xor
relational_operator ::=   =   | /=  | <   | <= | > | >=
binary_adding_operator ::=   +   | –   | &
unary_adding_operator ::=   +   | –
multiplying_operator ::=   *   | /   | mod | rem
highest_precedence_operator ::=   **  | abs | not
Discussion: Some of the above syntactic categories are not used in other syntax rules. They are just used for classification. The others are used for both classification and parsing.

Static Semantics

For a sequence of operators of the same precedence level, the operators are associated with their operands in textual order from left to right. Parentheses can be used to impose specific associations.
Discussion: The left-associativity is not directly inherent in the grammar of 4.4, though in 1.1.4 the definition of the metasymbols {} implies left associativity. So this could be seen as redundant, depending on how literally one interprets the definition of the {} metasymbols.
See the Implementation Permissions below regarding flexibility in reassociating operators of the same precedence. 
{predefined operator} {operator (predefined)} For each form of type definition, certain of the above operators are predefined; that is, they are implicitly declared immediately after the type definition. {binary operator} {operator (binary)} {unary operator} {operator (unary)} For each such implicit operator declaration, the parameters are called Left and Right for binary operators; the single parameter is called Right for unary operators. [An expression of the form X op Y, where op is a binary operator, is equivalent to a function_call of the form "op"(X, Y). An expression of the form op Y, where op is a unary operator, is equivalent to a function_call of the form "op"(Y). The predefined operators and their effects are described in subclauses 4.5.1 through 4.5.6.] 

Dynamic Semantics

[{Constraint_Error (raised by failure of run-time check)} The predefined operations on integer types either yield the mathematically correct result or raise the exception Constraint_Error. For implementations that support the Numerics Annex, the predefined operations on real types yield results whose accuracy is defined in Annex G, or raise the exception Constraint_Error. ]
To be honest: Predefined operations on real types can “silently” give wrong results when the Machine_Overflows attribute is false, and the computation overflows. 

Implementation Requirements

{Constraint_Error (raised by failure of run-time check)} The implementation of a predefined operator that delivers a result of an integer or fixed point type may raise Constraint_Error only if the result is outside the base range of the result type.
{Constraint_Error (raised by failure of run-time check)} The implementation of a predefined operator that delivers a result of a floating point type may raise Constraint_Error only if the result is outside the safe range of the result type. 
To be honest: An exception is made for exponentiation by a negative exponent in 4.5.6.

Implementation Permissions

For a sequence of predefined operators of the same precedence level (and in the absence of parentheses imposing a specific association), an implementation may impose any association of the operators with operands so long as the result produced is an allowed result for the left-to-right association, but ignoring the potential for failure of language-defined checks in either the left-to-right or chosen order of association. 
Discussion: Note that the permission to reassociate the operands in any way subject to producing a result allowed for the left-to-right association is not much help for most floating point operators, since reassociation may introduce significantly different round-off errors, delivering a result that is outside the model interval for the left-to-right association. Similar problems arise for division with integer or fixed point operands.
Note that this permission does not apply to user-defined operators. 
11  The two operands of an expression of the form X op Y, where op is a binary operator, are evaluated in an arbitrary order, as for any function_call (see 6.4). 


Examples of precedence:
not Sunny or Warm    --  same as (not Sunny) or Warm
X > 4.0 and Y > 0.0  --  same as (X > 4.0) and (Y > 0.0)
-4.0*A**2            --  same as –(4.0 * (A**2))
abs(1 + A) + B       --  same as (abs (1 + A)) + B
Y**(-3)              --  parentheses are necessary
A / B * C            --  same as (A/B)*C
A + (B + C)          --  evaluate B + C before adding it to A 

Wording Changes from Ada 83

We don't give a detailed definition of precedence, since it is all implicit in the syntax rules anyway.
The permission to reassociate is moved here from RM83-11.6(5), so it is closer to the rules defining operator association.

Contents   Index   References   Search   Previous   Next 
Ada-Europe Sponsored by Ada-Europe