CVS difference for ais/ai-00186.txt

Differences between 1.1 and version 1.2
Log of other versions for file ais/ai-00186.txt

--- ais/ai-00186.txt	1998/09/30 00:17:34	1.1
+++ ais/ai-00186.txt	1999/03/22 23:42:41	1.2
@@ -1,21 +1,142 @@
-!standard 03.05.04 (14)                               97-03-19  AI95-00186/01
-!class confirmation 97-03-19
+!standard 03.05.04 (14)                               99-03-21  AI95-00186/02
+!standard 03.04 (9)
+!class binding interpretation 99-03-21
 !status work item 97-03-19
 !status received 97-03-19
 !priority Low
-!difficulty Easy
+!difficulty Medium
 !subject Range of root_integer
 
-!summary 97-03-19
+!summary 99-03-21
 
-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
-
+An implementation may support integer or modular types which include
+values outside the range System.Min_Int..System.Max_Int.  In some cases
+evalutation of a non-static root_integer expression outside this range is
+required not to raise an exception.  In most other such cases, the behavior
+is defined to be implementation dependent.
+
+!question 99-03-21
+
+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;
+
+Is the evaluation of the expression allowed to raise Constraint_Error if P
+is instantiated with the largest modular type? (No.)
+
+!recommendation 99-03-21
+
+If an implementation supports a modular type whose range exceeds
+0..System.Max_Int, or a nonstandard integer type with values outside
+System.Min_Int..System.Max_Int, non-static expressions which involve only
+variables, constants, and attributes of the a type T or its subtypes, or
+numeric_literals and other values of type root_integer may only raise
+Constraint_Error if the process of evaluating the expression exceeds the
+range of type T.
+
+If a non-static expression contains arithmetic operators of type root_real,
+it is implementation defined whether or not Constraint_Error will be raised
+if the result is outside the range of root_real, even if the result of the
+expression is within the range of the target type.
+
+Let T be an integer or modular type which has values outside the range
+System.Min_Int..System.Max_Int.  If a non-static expression of type
+root_integer has both an attribute, variable or result of type T and an
+attribute, variable or result of some other type, it is erroneous for the
+value of the expression to exceed the range of root_integer.
+
+An implementation is allowed to choose a range for root_real that exceeds
+System.Min_Int..System.Max_Int.
+
+!wording 99-03-21
+
+The second sentence of paragraph 3.4(9) should read:
+
+"For a scalar type {declared by a derived_type_definition}, the
+base range of the derived type is the same as that of the parent type."
+
+Paragraph 3.5.4(14) should read:
+
+"A type defined by an integer_type_definition is implicitly derived
+from _root_integer_, an anonymous predefined (specific) integer type,
+whose base range is {at least} 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 thier use with the operations of any integer type."
+
+!discussion 99-03-21
+
+The first wording change above is just to eliminate an apparent conflict in
+the standard.  The second sentence of 3.5.4(14) is correct, but since all
+integer types are derived types, the paragraphs conflict.
+
+The main problem dealt with here is caused by the preference rule (see
+8.6(29)) for root_integer.  In theory this can cause expressions which
+appear to involve only operations of of one numeric type to actually be
+evaluated using the operations of root_integer.  Consider for instance the
+expression T'Val(T'Pos(X) - 3) where X is of type T.
+
+Although all the values in the expression are of either type T or
+universal_integer, the subtraction operation is that of root_integer.
+This seems irksome, but unlikely to occur even inside a generic with a
+formal of a discrete type.  However, there are more troubling cases.
+Consider the Boolean expression S'Modulus > T'Modulus, where S and T are
+modular subtypes.  When is this illegal, guaranteed to work, or can
+possibly raise Constraint_Error?  If the answer depends on the staticness
+of the subtypes, that way lies madness.  (Note that in this particular
+case, the expression can always be evaluated at compile time even if the
+subtypes are static or generic formal subtypes.)
+
+Even more troubling is this case:
+
+type Modular is mod System.Max_Binary_Modulus;
+..
+subtype Mod is Modular range...;
+..
+Base_Modulus: constant := Mod'Modulus;
+
+Does this or should this raise Constraint_Error, or is it implementation
+dependent? (It is implementation dependent if the subtype is non-static.)
+
+Now let's look at the other side for a minute.  There are some truly ugly
+cases such as  X: Integer := Modular'Pos(Y) + Integer'Pos(Z); where Y and Z
+are varibles of the respective types.  Here we have an expression that can
+only be evaluated at run-time, and possibly no machine arithmetic types
+that can be used safely, assuming that Integer and Modular are the largest
+available integer and modular types respectively.
+
+The conclusion is that implementations should always be allowed to "do the
+right thing" in the reasonable cases, and required not to raise
+Constraint_Error in expressions without attributes of a single type but no
+arithmetic operations.  But rather than force implementations not to
+provide otherwise useful types by requiring support of some pathological
+cases, these case are made erroneous.  It would be possible to make these
+cases a bounded error, but such mixed expressions can (and should) always
+be rewritten to make explicit which operations should be modular and where
+overflow is wanted.  By making such expressions erroneous only if they
+exceed the range of root_integer, programmers can still use such
+expressions if they know the possible ranges of all intermediate results.
+
+Finally this AI allows the range of root_integer to exceed
+System.Min_Int..System.Max_Int.  There is no point in allowing nonstandard
+integer types if the implementations are then restricted from using them
+where appropriate.  For example, on a machine with a double-width
+multiplication result and easy addition and subtraction for such values, it
+would be useful to have that type as a nonstandard integer type, even if
+some multiplication operators were not provided, and you couldn't use it
+for indexing.  It would be silly to prohibit using that type for evaluating
+expressions of type root_real.  Where possible this is the best solution to
+the problem.
 
 !appendix 97-03-19
 

Questions? Ask the ACAA Technical Agent