From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,e8c8d1c63ffacf0d X-Google-Attributes: gid103376,public From: ka@hiway1.exit109.com (Kenneth Almquist) Subject: Re: Constraint checking of actuals passed to Attributes Date: 2000/05/22 Message-ID: X-Deja-AN: 626017060 References: <391250A8.99D1585C@hotmail.com> <39171B69.2F983487@averstar.com> <8f93lm$1es$1@nnrp1.deja.com> <8f9snr$vbr$1@nnrp1.deja.com> Organization: Posted via Supernews, http://www.supernews.com Newsgroups: comp.lang.ada Originator: ka@exit109.com (Ken Lamquist) X-Complaints-To: newsabuse@supernews.com Date: 2000-05-22T00:00:00+00:00 List-Id: Robert A Duff wrote: > I suppose I could try expressing the intent by example: > > If you say: > > Uninit: Integer; -- Uninitialized variable! > ... > if Uninit < 10 then > ... > > The condition must be either True or False, or it must raise an > exception. It must not destroy other variable's values. Inside the > if statement, Uninit must evaluate to a value less than 10. > > Obviously that's not a formal definition -- it's just an example of the > intent. > > If I could give a formal definition of the intent, I would have done so > in the RM -- I didn't then, because it's hard, and it's still hard > today. I don't think it's impossible to formalize that intent. > > If you start asking me about floating-point NaN's, or holes in > rep-speced enums, I'll start hemming and hawing. But for plain old > integers and enums, I think I kown what was "intended". > > At least I can give lots of examples. ;-) As I understand it, the main reason for deviating from Ada 83 was that in Ada 83 an uninitialized variable could result in memory overwrites when used as a subscript and wild jumps when used in a case statement: type Index is new Integer range 1 .. 5; A : array(Index) of Integer; I : Index; A(I) := 1; -- The compiler need not check that I is in 1..5. case I is -- The compiler may generate code that branches ... -- to an arbitrary location if I is not in 1..5. end case; Fixing these two problems is tedious, but not particularly hard. In outline: 1. The value of an uninitialized scalar variable or scalar component of a composite type is either a valid value of the specified subtype, or an "illegal value." 2. If the value of X is an illegal value, then X'Valid is false. 3. If the value of X is an illegal value, then reading the value of X is a bounded error. The possible results are: 1. Program_Error is raised, 2. Constraint_Error is raised, 3. the result is an illegal value, or 4. the result is some valid value. 4. If X names a scalar object, then assigning an illegal value to X is a bounded error. The possible effects are: 1. Program_Error is raised, 2. Constraint_Error is raised, 3. X is set to an illegal value, or 4. X is set to some valid value. 5. Using an illegal value as the operand to a predefined operator, or as the argument to a function specified by the attributes S'floor, S'ceil, S'adjacent, S'leading_part, S'length, S'max, S'min, S'pos, S'pred, S'succ, or S'val, is a bounded error. The possible results are the same as those for reading a variable with an illegal value. 6. The result of applying the T'Image operation to an illegal value is implementation defined. 7. Using an illegal value as a subscript is a bounded error. The possible results are: 1. Program_Error is raised, 2. Constraint_Error is raised, 3. a valid value is substituted for the illegal value, or 4. the result of the subscript operation refers to an "illegal object". 8. Reading the value of an illgal object or a component of an illegal object is a bounded error. If the type of the object or component is not a pointer type, then the possible results are the same as those for reading an uninitialized variable. Otherwise, the possibilities are that Program_Error is raised, Constraint_Error is raised, or a null pointer value is returned. 9. Writing to an illegal object is a bounded error. It has no effect except for possibly raising Program_Error or Constraint_ Error. 10. It is a bounded error to use an illegal value as the control value for an if, while, or case statement. The possible results are: 1. Program_Error is raised, 2. Constraint_Error is raised, 3. a valid value is substituted for the illegal value. 11. It is a bounded error for the limit on a range used in a subtype or array type specification to be an illegal value. The result is that the set of values included in the range is undefined. In addition, the use of attributes defined in terms of the illegal value (X'first, X'last, X'length) is a bounded error; the possible results are the same as those for reading an uninitalized variable. 12. It is a bounded error for the limit on the range in a "for" statement to be an illegal value. The results is that the sequence of values taken on by the control variable of the for loop is undefined. [We don't require the sequence to be finite because a sequence of length 2**64 (which is possible on 64 bit machines) is effectively infinite.] Probably I've missed a few cases, but it should be fairly obvious how to fill in the gaps. Your requirement that, "Inside the if statement, Uninit must evaluate to a value less than 10," does not have anything to do with safety that I can see (unless the value of Uinit is passed to a routine written in another language). So your example makes it clear that the intent goes beyond avoiding the memory overwrite and wild jump problems that I list at the start of this article. However, I still have no clue as to what this additional intent is. So my question is: Beyond avoiding the two problems that I identified above, what else was the team attempting to accompish? Kenneth Almquist