"Serve Lau" <ni***@qinqin.comwrites:
"Keith Thompson" <ks***@mib.orgschreef in bericht
news:ln************@nuthaus.mib.org...
>"Serve Lau" <ni***@qinqin.comwrites:
>>"compiler_newbie" <bh****@gmail.comschreef in bericht
news:f8**********************************@l28g20 00prd.googlegroups.com...
On Jun 11, 10:27 am, Ben Pfaff <b...@cs.stanford.eduwrote:
>
It is discarded because signed arithmetic overflow yields
undefined behavior.
Thanks for your responses and the mention of the compiler flag that
supports the "classic" behaviour.
it looks strange to me to first do an operation and then after that
check if the operation should've been done.
Why not just check before and code the expected behaviour yourself??
Really?
Consider this:
long long x = <some value>, y = <some other value>;
if (<multiplication would overflow>) {
printf("%lld * %lld would overflow\n");
}
else {
printf("%lld * %lld = %lld\n", x * y);
}
you're right, there are situations where it wouldnt make much sense
however in the case of x = -x its easy and cleaner to check before.
Checking that with full portability is slightly trickier than what I'm
guessing you're thinking of. It overflows if and only if
(LLONG_MIN < -LLONG_MAX && x == LLONG_MIN)
and you have to adjust it depending on the type of x (with no help
from the compiler if you get it wrong).
or take
x = x / y;
if (program_crashed())
{
printf("y was zero\n");
x = 0;
}
wouldnt make much sense either right.
It would make a great deal of sense if, rather than program_crashed(),
the language provided a way to detect any kind of arithmetic error.
For example, in Ada:
begin
X := X / Y;
exception
when Constraint_Error =>
-- handle overflow
end;
And I think you're forgetting a possibility. Assuming, again,
that x and y are of type long long, the division can overflow on a
two's-complement system if x == LLONG_MIN and y == -1. That's just
the kind of thing that programmer's can easily forget, and that
compilers can't forget.
Of course floating-point division can easily overflow if the right
operand has a magnitude less than 1.0.
In practice, most programmers, most of the time, just don't bother
doing these checks. We instead use types that we *think* (or hope)
are big enough to hold whatever values we need. It's almost the
numeric equivalent of gets() with an array that we *think* is big
enough to hold whatever the user enters (except that we have a bit
more control over the input).
*If* C provided a way to detect numeric overflow after the fact
without invoking undefined behavior, it could be a lot easier to
write safer software in C -- and if the checks were built into the
language, the compiler could potentially eliminate a lot of them,
in cases where it can prove that a given expression can't overflow.
As programmers, we'd have to apply that reasoning to every expression
in a program, and most of us aren't compulsive enough to do this
and get it right every single time.
--
Keith Thompson (The_Other_Keith)
ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"