!standard 03.05.04 (14) 97-03-19 AI95-00186/01
!class confirmation 97-03-19
!status work item 97-03-19
!status received 97-03-19
!priority Low
!difficulty Easy
!subject Range of root_integer
!summary 97-03-19
The base range of root_integer is System.Min_Int .. System.Max_Int.
This does not include some values of some modular types.
!question 97-03-19
!response 97-03-19
!appendix 97-03-19
!section 3.5.4(14)
!subject Range of root_integer
!reference RM95 3.5.4(14)
!from Pascal Leroy 97-03-10
!reference 97-15727.g Pascal Leroy 97-3-10>>
!discussion
The referenced paragraph defines the base range of root_integer as
System.Min_Int .. System.Max_Int. This range covers all signed integer types,
but it is possible for modular types to exceed System.Max_Int. Because
root_integer is the type used at runtime for many computations, the fact that
it doesn't cover all standard integer types has surprising consequences.
Consider for example:
generic
type T is (<>);
package P is
...
end P;
package body P is
B : Boolean := T'Pos (T'Last) = 3;
end P;
Assume a 32-bit architecture, where Min_Int is -2 ** 31, Max_Int is 2 ** 31 -
1, Max_Binary_Modulus is 2 ** 32, and Max_Nonbinary_Modulus is 2 ** 32 - 1.
Instantiating P with any signed integer type works fine, but if it is
instantiated with a modular type with 'Modulus greater than 2 ** 31, the
elaboration of B raises Constraint_Error because the result of the attribute
Pos exceeds Max_Int. This makes it very hard to write a generic that works
for any discrete type.
In fact, it is even very hard to write a generic that works for any modular
type. Consider a second example:
generic
type T is mod <>;
procedure P;
procedure P is
begin
if T'Modulus > 3 then
...
end if;
end P;
The conversion of T'Modulus to root_integer raises Constraint_Error.
_____________________________________________________________________
Pascal Leroy +33.1.30.12.09.68
pleroy@rational.com +33.1.30.12.09.66 FAX
****************************************************************