Ada 95 Quality and Style Guide Chapter 7

Chapter 7: Portability - TOC - 7.2 NUMERIC TYPES AND EXPRESSIONS

7.2.1 Predefined Numeric Types


  • Avoid using the predefined numeric types in package Standard. Use range and digits declarations and let the implementation pick the appropriate representation.
  • For programs that require greater accuracy than that provided by the global assumptions, define a package that declares a private type and operations as needed; see Pappas (1985) for a full explanation and examples.
  • Consider using predefined numeric types (Integer, Natural, Positive) for:

    - Indexes into arrays where the index type is not significant, such as type String
    - "Pure" numbers, that is, numbers with no associated physical unit (e.g., exponents)
    - Values whose purpose is to control a repeat or iteration count

  • example

    The second and third examples below are not representable as subranges of Integer on a machine with a 16-bit word. The first example below allows a compiler to choose a multiword representation, if necessary.


    type    Second_Of_Day is             range 0 .. 86_400;

    rather than:

    type    Second_Of_Day is new Integer range 1 .. 86_400;


    subtype Second_Of_Day is     Integer range 1 .. 86_400;


    An implementor is free to define the range of the predefined numeric types. Porting code from an implementation with greater accuracy to one of lesser accuracy is a time consuming and error-prone process. Many of the errors are not reported until run-time.

    This applies to more than just numerical computation. An easy-to-overlook instance of this problem occurs if you neglect to use explicitly declared types for integer discrete ranges (array sizes, loop ranges, etc.) (see Guidelines 5.5.1 and 5.5.2). If you do not provide an explicit type when specifying index constraints and other discrete ranges, a predefined integer type is assumed.

    The predefined numeric types are useful when you use them wisely. You should not use them to avoid declaring numeric types—then you lose the benefits of strong typing. When your application deals with different kinds of quantities and units, you should definitely separate them through the use of distinct numeric types. However, if you are simply counting the number of iterations in an iterative approximation algorithm, declaring a special integer type is probably overkill. The predefined exponentiation operators ** require an integer as the type of its right operand.

    You should use the predefined types Natural and Positive for manipulating certain kinds of values in the predefined language environment. The types String and Wide_String use an index of type Positive. If your code indexes into a string using an incompatible integer type, you will be forced to do type conversion, reducing its readability. If you are performing operations like slices and concatenation, the subtype of your numeric array index is probably insignificant and you are better off using a predefined subtype. On the other hand, if your array represents a table (e.g., a hash table), then your index subtype is significant, and you should declare a distinct index type.


    There is an alternative that this guideline permits. As Guideline 7.1.5 suggests, implementation dependencies can be encapsulated in packages intended for that purpose. This could include the definition of a 32-bit integer type. It would then be possible to derive additional types from that 32-bit type.

    < Previous Page Search Contents Index Next Page >
    1 2 3 4 5 6 7 8 9 10 11
    Appendix References Bibliography