From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Date: 22 Sep 93 00:21:11 GMT From: eachus@mitre-bedford.arpa (Robert I. Eachus) Subject: Re: Bug in AdaEd??? Message-ID: List-Id: In article <1993Sep21.041912.10460@rational.com> geneo@Rational.COM (Gene Ouye) writes: > I can see how the expression "not a" would never raise an exception > (because "not" operates on the base type (Boolean) and returns a > value of the base Boolean type), but it seems that assigning it to > something belonging to a constrained subtype should raise > Constraint_Error (except possibly in cases where the compiler can > assume that the value to be assigned is invalid, as described > below). I think you understand, you just find the situation very uncomfortable. That's just how the ARG feels. (IMHO in any case.) Let me drag the logic out into plain (ugly) sight. 1) The value of A can never be other than True. 2) Therefore an optimizing compiler can eliminate any assignments to A. 3) If the compiler eliminates the assignment, it can also (see 11.6) eliminate the check. 4) So in both this example and your new example the compiler is allowed and encouraged to eliminate the check. 5) The program author IN WHOSE MIND the check was meaningful is upset. When Ada 83 was being defined, the principle reason for the constraint checks on assignments was to prevent objects from having invalid values. In the tradeoffs between speed and correctness, the compromise was that initial values need not be checked (the raw bits in memory allocated to the object, not the initial value expression) for objects other than access types, but all subsequent assignments would be. The case of assignments which were eliminated by optimization was discussed, and 11.6(7) was the result. If you don't do the assignment, you don't need to do the check. But there are nasty examples where you need to rely on CONSTRAINT_ERROR being raised. The worst example we came up with was: declare subtype My_Int is Integer range 1..10_000; X,Y: My_Int; Junk: My_Int; begin Read(X); Read(Y); Junk := X*Y; if Junk > 10_000 then Do_Something; end if; exception when others => Do_Something; end; It seems clear that if you enter 999 and 1234, Do_Something will be called. But on some compilers, at some optimization levels, it won't be! The condition is obviously always false, so the if statement can be eliminated. The value of Junk is now never read and therefore Junk can be elimiated, as can the assignment to it. You finish by eliminating the multiplication of X and Y. (This example is not pathological. One place where similar code occurs frequently is in compilers. You want to warn the author of the program being compiled that his array is too big, but you don't really care what the actual size is...at least not in the front end of the compiler.) Obviously, we as human readers can see that the progammer wanted CONSTRAINT_ERROR to occur in some conditions. But try to write code that a compiler which knows little outside the RM rules (including 11.6) rules cannot optimize away. It's not easy. -- Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is...