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=-0.9 required=3.0 tests=BAYES_00,FROM_ADDR_WS autolearn=no autolearn_force=no version=3.4.5-pre1 Date: 22 Sep 93 14:22:46 GMT From: newsgate.watson.ibm.com!yktnews.watson.ibm.com!ncohen@uunet.uu.net (Norm an H. Cohen) Subject: Re: Bug in AdaEd??? Message-ID: List-Id: In article , groleau@e7sa.crd.ge.com (Wes Groleau x1240 C73-8) writes: |> Language lawyers please explain in short words if I'm wrong, but I can't |> for the life of me think of ANY reason why optimization of code with |> predetermined results would intentionally be done to give different results! Here is a summary of RM 11.6 "while standing on one foot": An optimizer is allowed to assume that the intended effect of a program is not to raise a predefined exception. This allows optimizers to produce faster code that behaves in the same way as unoptimized code IN ALL CASES WHERE THE UNOPTIMIZED CODE WOULD NOT RAISE AN EXCEPTION. To a programmer who does not intend to raise an exception, the occurrence of an exception is a failure. In all executions that do not fail, the optimizations preserve the behavior of the program. However, if, contrary to the assumption allowed by RM 11.6, the programmer INTENDS to raise exceptions, it will seem to him as though the optimizations, in Wes Groleau's words, "give different results." Consider the following program, where there are no references to X after the loop, N is of subtype Positive, and Capacity is a named number reflecting some property of the execution environment: X := A * B; while N < Capacity loop [references to X] end loop; The source code is written to be easily portable to environments in which different values of Capacity are appropriate: It is necessary only to modify the declaration of Capacity and recompile. Today we are recompiling this code for a system in which Capacity is declared to be zero. The optimizer observes that the condition N < Capacity is necessarily false, so the entire loop can be eliminated. Once the loop is eliminated, the variable X becomes "dead", that is, there is no reference to its value. Can the optimizer therefore go one step further and eliminate the statement X := A * B; ? In the absence of RM 11.6, the answer would be no, because the multiplication might overflow and raise Constraint_Error, so eliminating the assignment statement could change the effect of the program. RM 11.6 allows the optimizer to assume that this particular aspect of the original program's behavior--ensuring that Constraint_Error is raised whenever A * B would overflow--is not a part of the behavior the programmer intends to achieve, but an accidental consequence of the need to compute A * B in cases where the loop cannot be eliminated. Of course there is a middle ground between the programmer who says, "If my program raises an exception, it has failed anyway. Don't make my program slower to ensure that it fails in one state rather than another," and the programmer who expects to raise an exception in certain cases (e.g., as a method of checking whether the product A * B is within a certain range). That middle ground is occupied by the programmer who doesn't expect to raise an exception, but considers the occurrence of an exception as a recoverable error rather than a total failure. Such a programmer does care about the behavior of a program even in the cases where an exception is raised. The difficulty that the ARG has had with RM 11.6 is attributable to this tension between the programmer who does not expect to be able to recover when an exception is raised, and thus does not want considerations of behavior in the presence of exceptions to slow down his code, and the programmer who expects to be able to recover from an exception, and thus wants to be able to predict and control the state of a program that has raised an exception. -- Norman H. Cohen ncohen@watson.ibm.com