Ada '83 Quality and Style, Sec 5.10: Chapter 5 Summary
Ada '83 Quality and Style:
Guidelines for Professional Programmers
CHAPTER 5: Programming Practices
- Associate names with loops when they are nested.
- Associate names with blocks when they are nested.
- Use loop names on all exit statements from nested loops.
- Include the simple name at the end of a package specification and body.
- Include the simple name at the end of a task specification and body.
- Include the simple name at the end of an accept statement.
- Include the designator at the end of a subprogram body.
- Name formal parameters descriptively to reduce the need for comments.
- Use named parameter association in calls of infrequently used
subprograms or entries with many formal parameters.
- Use named association when instantiating generics.
- Use named association for clarification when the actual parameter is
any literal or expression.
- Use named association when supplying a nondefault value to an optional parameter.
- Provide default parameters to allow for occasional, special use of
widely used subprograms or entries.
- Place default parameters at the end of the formal parameter list.
- Consider providing default values to new parameters added to an
existing subprogram.
- Show the mode indication of all procedure and entry parameters.
- Use
in out only when the parameter is both read from and updated.
- Use existing types as building blocks by deriving new types from them.
- Use range constraints on subtypes.
- Define new types, especially derived types, to include the largest set of possible values, including boundary values.
- Constrain the ranges of derived types with subtypes, excluding
boundary values.
- Avoid anonymous types.
- Use anonymous types for array variables when no suitable type exists
and the array will not be referenced as a whole.
- Use limited private types in preference to private types.
- Use private types in preference to nonprivate types.
- Explicitly export needed operations rather than easing restrictions.
- Use records to group heterogeneous but related data.
- Consider records to map to I/O device data.
- Record structures should not always be flat. Factor out common parts.
- For a large record structure, group related components into smaller
subrecords.
- For nested records, pick element names that read well when inner
elements are referenced.
- Differentiate between static and dynamic data. Use dynamically
allocated objects with caution.
- Use dynamically allocated data structures only when it is necessary to create and destroy them dynamically or to be able to reference them by
different names.
- Do not drop pointers to undeallocated objects.
- Do not leave dangling references to deallocated objects.
- Initialize all access variables and components within a record.
- Do not rely on memory deallocation.
- Deallocate explicitly.
- Use length clauses to specify total allocation size.
- Provide handlers for
Storage_Error.
- Use
'First or 'Last instead of numeric literals to represent the first or last values of a range.
- Use the type or subtype name of the range instead of
'First .. 'Last.
- Use array attributes
'First, 'Last, or 'Length instead of numeric
literals for accessing arrays.
- Use the
'Range of the array instead of the name of the index subtype
to express a range.
- Use
'Range instead of 'first .. 'Last to express a range.
- Use parentheses to specify the order of subexpression evaluation to
clarify expressions.
- Use parentheses to specify the order of evaluation for subexpressions
whose correctness depends on left to right evaluation.
- Avoid names and constructs that rely on the use of negatives.
- Choose names of flags so they represent states that can be used in
positive form.
- Use short-circuit forms of the logical operators.
- Use
<= and >= in relational expressions with real operands instead of =.
- Minimize the depth of nested expressions.
- Minimize the depth of nested control structures.
- Try simplification heuristics.
- Use slices rather than a loop to copy part of an array.
- Never use an
others choice in a case statement.
- Do not use ranges of enumeration literals in case statements.
- Use for loops whenever possible.
- Use while loops when the number of iterations cannot be calculated
before entering the loop, but a simple continuation condition can be applied
at the top of the loop.
- Use plain loops with exit statements for more complex situations.
- Avoid exit statements in while and for loops.
- Minimize the number of ways to exit a loop.
- Use exit statements to enhance the readability of loop termination
code.
- Use
exit when ... rather than if ... then exit whenever possible.
- Review exit statement placement.
- Consider specifying bounds on loops.
- Consider specifying bounds on recursion.
- Do not use goto statements.
- Minimize the number of returns from a subprogram.
- Highlight returns with comments or white space to keep them from being lost in other code.
- Use blocks to localize the scope of declarations.
- Use blocks to perform local renaming.
- Use blocks to define local exception handlers.
- Use an aggregate instead of a sequence of assignments to assign values to all components of a record.
- Use an aggregate instead of a temporary variable when building a
record to pass as an actual parameter.
- Use positional association only when there is a conventional ordering
of the arguments.
- Minimize using the
use clause.
- Consider using the
use clause in the following situations:
- Infix operators are needed
- Standard packages are needed and no ambiguous references are introduced
- References to enumeration literals are needed
- Consider the
renames clause to avoid the use clause.
- Localize the effect of all
use clauses.
- Rename a long, fully qualified name to reduce the complexity if it
becomes unwieldy (Guideline 3.1.4).
- Rename declarations for visibility purposes rather than using the
use
clause, especially for infix operators (Guideline 5.7.1).
- Rename parts when interfacing to reusable components originally
written with nondescriptive or inapplicable nomenclature.
- Use a project-wide standard list of abbreviations to rename common
packages.
- Limit overloading to widely used subprograms that perform similar
actions on arguments of different types.
- Preserve the conventional meaning of overloaded operators.
- Use
"+" to identify adding, joining, increasing, and enhancing kinds of functions.
- Use
"-" to identify subtraction, separation, decreasing, and depleting kinds of functions.
- Do not depend on the definition of equality provided by private types.
- When overloading the equality operator for limited private types,
maintain the properties of an algebraic equivalence relation.
- Avoid causing exceptions to be raised when it is easy and efficient to do so.
- Provide handlers for exceptions which cannot be avoided.
- Use exception handlers to enhance readability by separating fault
handling from normal execution.
- Do not use exceptions and exception handlers as goto statements.
- Use caution when programming handlers for
others.
- Provide a handler for
others in suitable frames to protect against unexpected exceptions being propagated without bound, especially in safety critical systems.
- Use
others only to catch exceptions you cannot enumerate explicitly, preferably only to flag a potential abort.
- Avoid using
others during development.
- Handle all exceptions, both user and predefined.
- For every exception that might be raised, provide a handler in
suitable frames to protect against undesired propagation outside the abstraction.
- Do not rely on being able to identify the fault raising predefined or
implementation-defined exceptions.
- Use blocks to associate localized sections of code with their own
exception handlers.
- Use
Unchecked_Conversion only with the utmost care.
- Ensure the value resulting from
Unchecked_Conversion is in range.
- Isolate the use of
Unchecked_Conversion in package bodies.
- Isolate the use of
Unchecked_Deallocation in package bodies.
- Do not write code whose correct execution depends on the particular
parameter passing mechanism used by an implementation.
- Use address clauses to map variables and entries to the hardware
device or memory, not to model the FORTRAN "equivalence" feature.
- Do not suppress exception checks during development.
- Minimize suppression of exception checks during operation.
- If necessary, introduce blocks that encompass the smallest range of
statements that can safely have exception checking removed.
- Initialize all objects prior to use.
- Ensure elaboration of an entity before using it.
- Use function calls in declarations cautiously.
- Ensure that values obtained from
Direct_IO and Sequential_IO are in
range.
- Avoid depending on the order in which certain constructs in Ada are
evaluated.
Back to document index
This file was converted with TextToHTML - (c) Logic n.v.