Language Ref Manual references: 4.4 Expressions
In this section...
5.5.1 Range Values
5.5.2 Array Attributes
5.5.3 Parenthetical Expressions
5.5.4 Positive Forms of Logic
5.5.5 Short Circuit Forms of the Logical Operators
5.5.6 Accuracy of Operations With Real Operands
|Summary of Guidelines from this section|
'Lastinstead of numeric literals to represent the first or last values of a range.
First .. 'Last.
type Temperature is range All_Time_Low .. All_Time_High; type Weather_Stations is range 1 .. Max_Stations; Current_Temperature : Temperature := 60; Offset : Temperature; ... for I in Weather_Stations loop Offset := Current_Temperature - Temperature'First; ... end loop;
Weather_Stations'First .. Weather_Stations'Lastor
1 .. Max_Stations, because it is clearer, less error-prone, and less dependent on the definition of the type
Weather_Stations. Similarly, it is better to use
Temperature'Firstin the offset calculation than to use
All_Time_Low, because the code will still be correct if the definition of the subtype
Temperatureis changed. This enhances program reliability.
type Large_Range is new Integer; subtype Small_Range is Large_Range range 1 .. 10;
then the first declaration below works fine, but the second one is probably an accident and raises an exception on most machines because it is requesting a huge array (indexed from the smallest integer to the largest one):
Array_1 : array (Small_Range) of Integer; Array_2 : array (Large_Range) of Integer;
Language Ref Manual references: 3.3.2 Subtype Declarations, 3.5 Scalar Types, 3.6 Array Types, 5.5 Loop Statements, A Predefined Language Attributes
subtype Name_String is String (1 .. Name_Length); File_Path : Name_String := (others => ' '); ... for I in File_Path'Range loop ... end loop;
Name_String'Rangein the for loop than to use
Name_String'First .. Name_String'Last, or
1 .. 30, because it is clearer, less error-prone, and less dependent on the definitions of
Name_Stringis changed to have a different index type, or if the bounds of the array are changed, this will still work correctly. This enhances program reliability.
Language Ref Manual references: 3.6 Array Types, 3.6.1 Index Constraints and Discrete Ranges, A Predefined Language Attributes
(1.5 * X**2)/A - (6.5*X + 47.0) 2*I + 4*Y + 8*Z + C
5 + ((Y ** 3) mod 10)
is clearer, and equivalent to
5 + Y**3 mod 10
The rules of evaluation do specify left to right evaluation for operators with the same precedence level. However, it is the most commonly overlooked rule of evaluation when checking expressions for correctness.
Language Ref Manual references: 4.4 Expressions, 4.5 Operators and Expression Evaluation, 4.5.6 Highest Precedence Operators
if Operator_Missing then
rather than either
if not Operator_Found then
if not Operator_Missing then
Language Ref Manual references: 2.3 Identifiers, 4.5.1 Logical Operators and Short-circuit Control Forms
if Y /= 0 or else (X/Y) /= 10 then
if Y /= 0 then
if (X/Y) /= 10 then
rather than either
if Y /= 0 and (X/Y) /= 10 then
or to avoid Numeric_Error
if (X/Y) /= 10 then
if Target /= null and then Target.Distance < Threshold then
if Target.Distance < Threshold then
to avoid referencing a field in a non-existent object.
In the absence of short-circuit forms, Ada does not provide a guarantee of the
order of expression evaluation, nor does the language guarantee that
evaluation of a relational expression is abandoned when it becomes clear that
it evaluates to
Language Ref Manual references: 4.5.1 Logical Operators and Short-circuit Control Forms
>=in relational expressions with real operands instead of
Current_Temperature : Temperature := 0.0; Temperature_Increment : Temperature := 1.0 / 3.0; Maximum_Temperature : constant := 100.0; ... loop ... Current_Temperature := Current_Temperature + Temperature_Increment; ... exit when Current_Temperature >= Maximum_Temperature; ... end loop;
The Ada definition of model intervals also means that the use of
<= is more
portable than either
=would have to be used. But never use
=on real operands as a condition to exit a loop.
honey Language Ref Manual references: 3.5.6 Real Types, 4.5.2 Relational Operators and Membership Tests, 4.5.7 Accuracy of Operations with Real Operands