Ada Conformity Assessment Authority |
Home |
Conformity Assessment | Test Suite |
ARG | Ada Standard |

An
integer_type_definition
defines an integer type; it defines either a *signed* integer type,
or a *modular* integer type. The base range of a signed integer
type includes at least the values of the specified range. A modular type
is an integer type with all arithmetic modulo a specified positive *modulus*;
such a type corresponds to an unsigned type with wrap-around semantics.

{*AI12-0444-1*}
Each simple_expression
in a signed_integer_type_definition
is expected to be of any integer type; they can
be of different integer types need not be
of the same type. The expression
in a modular_type_definition
is likewise expected to be of any integer type.

The simple_expressions
of a signed_integer_type_definition
shall be static, and their values shall be in the range System.Min_Int
.. System.Max_Int.

The
expression
of a modular_type_definition
shall be static, and its value (the *modulus*) shall be positive,
and shall be no greater than System.Max_Binary_Modulus if a power of
2, or no greater than System.Max_Nonbinary_Modulus if not.

The set of values for a signed integer type is the
(infinite) set of mathematical integers[, though only values of the base
range of the type are fully supported for run-time operations]. The set
of values for a modular integer type are the values from 0 to one less
than the modulus, inclusive.

A signed_integer_type_definition
defines an integer type whose base range includes at least the values
of the simple_expressions
and is symmetric about zero, excepting possibly an extra negative value.
A signed_integer_type_definition
also defines a constrained first subtype of the type, with a range whose
bounds are given by the values of the simple_expressions,
converted to the type being defined.

A modular_type_definition
defines a modular type whose base range is from zero to one less than
the given modulus. A modular_type_definition
also defines a constrained first subtype of the type with a range that
is the same as the base range of the type.

There is a predefined signed
integer subtype named Integer[, declared in the visible part of package
Standard]. It is constrained to the base range of its type.

A
type defined by an integer_type_definition
is implicitly derived from *root_integer*, an anonymous predefined
(specific) integer type, whose base range is System.Min_Int .. System.Max_Int.
However, the base range of the new type is not inherited from *root_integer*,
but is instead determined by the range or modulus specified by the integer_type_definition.
[Integer literals are all of
the type *universal_integer*, the universal type (see 3.4.1)
for the class rooted at *root_integer*, allowing their use with
the operations of any integer type.]

{*8652/0099*}
{*AI95-00152-01*}
Note that this derivation does not imply any inheritance of subprograms.
Subprograms are inherited only for types derived by a derived_type_definition
(see 3.4), or a private_extension_declaration
(see 7.3, 7.3.1,
and 12.5.1).

{*AI95-00340-01*}
For every modular subtype S, the following attributes are defined:

S'Mod

This function returns *Arg* **mod**
S'Modulus, as a value of the type of S.

S'Modulus

The elaboration of an integer_type_definition
creates the integer type and its first subtype.

For a modular type, if the result of the execution
of a predefined operator (see 4.5) is outside
the base range of the type, the result is reduced modulo the modulus
of the type to a value that is within the base range of the type.

For
a signed integer type, the exception Constraint_Error is raised by the
execution of an operation that cannot deliver the correct result because
it is outside the base range of the type. [
For any integer type, Constraint_Error is raised
by the operators "/", "**rem**", and "**mod**"
if the right operand is zero.]

If Long_Integer is predefined
for an implementation, then its range shall include the range –2**31+1
.. +2**31–1.

System.Max_Binary_Modulus shall be at least 2**16.

{*AI12-0444-1*}
For the execution of a predefined operation of a signed integer type,
it is optional to the
implementation need not raise Constraint_Error if the result is
outside the base range of the type, so long as the correct result is
produced.

An implementation
may provide additional predefined signed integer types[, declared in
the visible part of Standard], whose first subtypes have names of the
form Short_Integer, Long_Integer, Short_Short_Integer, Long_Long_Integer,
etc. Different predefined integer types are allowed to have the same
base range. However, the range of Integer should be no wider than that
of Long_Integer. Similarly, the range of Short_Integer (if provided)
should be no wider than Integer. Corresponding recommendations apply
to any other predefined integer types. An implementation
may support There need not be a named integer
type corresponding to each distinct base ranges
for which there is no corresponding named integer type range
supported by an implementation. The range of each first subtype
should be the base range of its type.

{*AI12-0444-1*}
**Implementation defined: **The predefined integer types declared
in Standard.

{*AI12-0444-1*}
An implementation may provide *nonstandard integer
types*, descendants of *root_integer* that are declared outside
of the specification of package Standard, which may
have different need not have all the standard
characteristics than of
a type defined by an integer_type_definition.
For example, a nonstandard integer type can might
have an asymmetric base range or it can be disallowed might
not be allowed as an array or loop index (a very long integer).
Any type descended from a nonstandard integer type is also nonstandard.
An implementation may place arbitrary restrictions on the use of such
types; it is implementation defined whether operators that are predefined
for “any integer type” are defined for a particular nonstandard
integer type. [In any case, such types are not permitted as explicit_generic_actual_parameters
for formal scalar types — see 12.5.2.]

For a one's complement machine,
the high bound of the base range of a modular type whose modulus is one
less than a power of 2 may be equal to the modulus, rather than one less
than the modulus. It is implementation defined for which powers of 2,
if any, this permission is exercised.

{*8652/0003*}
{*AI95-00095-01*}
For a one's complement machine, implementations may support nonbinary
modulus values greater than System.Max_Nonbinary_Modulus. It is implementation
defined which specific values greater than System.Max_Nonbinary_Modulus,
if any, are supported.

An implementation should support
Long_Integer in addition to Integer if the target machine supports 32-bit
(or longer) arithmetic. No other named integer subtypes are recommended
for package Standard. Instead, appropriate named integer subtypes should
be provided in the library package Interfaces (see B.2).

An implementation for a two's
complement machine should support modular types with a binary modulus
up to System.Max_Int*2+2. An implementation should support a nonbinary
modulus up to Integer'Last.

NOTE 1 Integer
literals are of the anonymous predefined integer type *universal_integer*.
Other integer types have no literals. However, the overload resolution
rules (see 8.6, “The
Context of Overload Resolution”) allow expressions of the type
*universal_integer* whenever an integer type is expected.

NOTE 2 The same arithmetic operators
are predefined for all signed integer types defined by a signed_integer_type_definition
(see 4.5, “Operators
and Expression Evaluation”). For modular types, these same
operators are predefined, plus bit-wise logical operators (**and**,
**or**, **xor**, and **not**). In addition, for the unsigned
types declared in the language-defined package Interfaces (see B.2),
functions are defined that provide bit-wise shifting and rotating.

NOTE 3 Modular types match a generic_formal_parameter_declaration
of the form "**type** T **is mod** <>;"; signed
integer types match "**type** T **is range** <>;"
(see 12.5.2).

An implementation is allowed
to support any number of distinct base ranges for integer types, even
if fewer integer types are explicitly declared in Standard.

Modular (unsigned, wrap-around) types are new.

Ada 83's integer types are now called "signed"
integer types, to contrast them with "modular" integer types.

Standard.Integer, Standard.Long_Integer, etc.,
denote constrained subtypes of predefined integer types, consistent with
the Ada 95 model that only subtypes have names.

We now impose minimum requirements on the base
range of Integer and Long_Integer.

We no longer explain integer type definition
in terms of an equivalence to a normal type derivation, except to say
that all integer types are by definition implicitly derived from *root_integer*.
This is for various reasons.

First of all, the equivalence with a type derivation
and a subtype declaration was not perfect, and was the source of various
AIs (for example, is the conversion of the bounds static? Is a numeric
type a derived type with respect to other rules of the language?)

Secondly, we don't want to require that every
integer size supported shall have a corresponding named type in Standard.
Adding named types to Standard creates nonportabilities.

Thirdly, we don't want the set of types that
match a formal derived type "type T is new Integer;" to depend
on the particular underlying integer representation chosen to implement
a given user-defined integer type. Hence, we would have needed anonymous
integer types as parent types for the implicit derivation anyway. We
have simply chosen to identify only one anonymous integer type —
*root_integer*, and stated that every integer type is derived from
it.

Finally, the “fiction” that there
were distinct preexisting predefined types for every supported representation
breaks down for fixed point with arbitrary smalls, and was never exploited
for enumeration types, array types, etc. Hence, there seems little benefit
to pushing an explicit equivalence between integer type definition and
normal type derivation.

{*AI95-00340-01*}
The Mod attribute is new. It eases mixing of signed
and unsigned values in an expression, which can be difficult as there
may be no type which can contain all of the values of both of the types
involved.

{*8652/0003*}
{*AI95-00095-01*}
**Corrigendum:** Added additional permissions for modular types on
one's complement machines.

Ada 2005 and 2012 Editions sponsored in part by **Ada-Europe**