Marc.Graham@SEI.CMU.EDU (08/29/90)
Section 4.5.5 allows multiplication of an object of any fixed point type by an object of "the predefined type INTEGER" (Standard.Integer). Consider the following: ------------ procedure junk is type blarb is delta 0.1 range 0.0 .. 32769.0; thing : blarb; begin if thing * 32767 > thing * 32768 then null; end if; end junk; ---------- My Sun Alsys compliers complains in the following way: ------ 8 if thing * 32767 > thing * 32768 then <-1-> 1 *EXP This value is outside the range of the target type. NUMERIC_ERROR will be raised here at run time. ---- This complier will do 32-bit arithmetic, but Integer is 16 bits. Questions: 1) Is the Alsys complier correct in its complaint? (I think it is.) 2) Is there an Ada commentary or such to the effect: "Of course, when the manual *says* INTEGER it doesn't really *mean* INTEGER, ...."?
NCOHEN@IBM.COM ("Norman H. Cohen") (08/30/90)
Marc Graham questions the message indicating that NUMERIC_ERROR will be raised at the point of the numeric literal 32768 in the following program: procedure junk is type blarb is delta 0.1 range 0.0 .. 32769.0; thing : blarb; begin if thing * 32767 > thing * 32768 then null; end if; end junk; Technically, the exception is raised not by the multiplication, but by the implicit conversion of the universal integer value 32,768 to type Integer (which is 16 bits in Marc's implementation). This is explicitly justified by RM 3.5.4(10). However, an implementation is allowed to be more reasonable. That same paragraph goes on to say, "However, an implementation is not required to raise the exception NUMERIC_ERROR if the operation is part of a larger expression whose result can be computed correctly, as described in section 11.6." (The full rule is given in RM 11.6(5), which I will not quote here because all readings of that paragraph generate more questions than they answer.) In the example above, there are values of THING for which the enclosing expression can be successfully evaluated, so the compiler is not being as helpful as it could be. I wonder how it treats I: Integer := -32768; (in which evaluation of the initial value technically consists of conversion of the universal_integer value 32768 to type Integer followed by invocation of the negation operator for type Integer).
Marc.Graham@SEI.CMU.EDU (08/31/90)
Norm Cohen is correct in his description of why the Alsys compiler behaves the way it does. (To refresh your memory, the question concerns the following Ada text and the accompanying warning.) ------------ procedure junk is type blarb is delta 0.1 range 0.0 .. 32769.0; thing : blarb; begin if thing * 32767 > thing * 32768 then null; end if; end junk; ---------- My Sun Alsys compliers complains in the following way: ------ 8 if thing * 32767 > thing * 32768 then <-1-> 1 *EXP This value is outside the range of the target type. NUMERIC_ERROR will be raised here at run time. ---- Dr. Cohen failed to answer my real question, which is not surprising, considering that I failed to ask it. So my real question is: Why does LRM section 4.5.5, paragraph 10, use Standard.Integer instead of either UNIVERSAL_INTEGER (allowing multiplcation and division of fixeds by integer literals or named numbers) or "any integer type" (allowing those operations for any integer and fixed objects)? Those two alternatives are easily remembered and explained. The situation in 4.5.5 (10) allows for some, but not all, literals and some, but not all, non-literals. Is there any rhyme or reason to this? Marc H. Graham Software Engineering Institute marc@sei.cmu.edu Carnegie Mellon University (412) 268 7784 Pittsburgh, PA 15213