On Tue, Jun 28, 2005 at 10:23:51AM +0300, Michael Veksler wrote: On Jun 28, 2005, at 1:12 AM, Gabriel Dos Reis wrote: > > > So, > > > please, do refrain from reasoning like "since we did X for Y and Y was > > > undefined behaviour, we should do the same for Z." "Undefined > > > behaviour" isn't a 0 or 1 thingy, even though it is about computers. > > > You need to evaluate them on case-by-case basis.
Andrew Pinski wrote on 28/06/2005 08:34:25: > Gaby, I am not sure you can do that in a reliable way. You may end up > with different behavior of overflow in the following two cases: > 1. for (int i = x ; i <= y ; ++i) > { > // this loop can be eliminated - overflow case (y == MAX_INT) > // is undefined. > q= s + 5; // moved outside the loop. > } > 2. a = b + c; // modulo > > If you treat overflow in case 1 differently than in case 2 then > you get into many inconsistencies and corner cases. In digital logic optimization we speak of "don't cares". This means that we have certain input combinations that we don't care about, but we must produce correct logic for all the cases that we do care about. It's really just the same for producing a compiler that matches a spec: We want to produce the cheapest possible circuit/program, by taking maximal advantage of the degrees of freedom provided by the don't-cares. Andrew, you're exactly right that we can't define the behavior in a reliable way, and THAT IS EXACTLY THE POINT. We want to produce the most efficient possible implementation for the cases that *are* defined, and the behavior for the undefined cases naturally falls out of that. You've actually given us an excellent example above. Consider a processor whose integer addition instruction wraps. Then the cheapest implementation for examples 1 and 2 above that cover the defined cases is to eliminate the loop in case 1, and produce a modulo result in case 2. You worried about interaction between the two constructs. Consider /* int a, b, c; */ if (b > 0) { a = b + c; int count; for (int i = c; i <= a; i++) count++; some_func(count); } Since behavior on integer overflow is undefined, we can optimize assuming that overflow has not occurred. Then a > c, so the for loop always executes b+1 times, and we end up with if (b > 0) some_func(b+1); Any attempt to assign meaning to integer overflow would prevent this optimization.