4 ms·
> However, it was never meant to allow compiler to assume "ok, I can see your code is totally broken, so let's break it more, cause you don't care anyway". Tha
by loup-vaillant 9y ago
> However, it was never meant to allow compiler to assume "ok, I can see your code is totally broken, so let's break it more, cause you don't care anyway".
That's nevertheless how compiler writers are interpreting the standard right now. Take integer overflow for instance. Stuff like this:
unsigned u = some_computation();
int x = u; // because of reasons
x += 42; // hmm this may overflow, let's check that
if (x < 0) { // It's a 2's complement machine, this'll work
handle_overflow(x); // now, let's deal with the overflow
}
Now here's how your optimising compiler see that stuff:
unsigned u = some_computation();
int x = u; // x is always positive.
x += 42; // signed integer never overflow
if (x < 0) { // x was positive, no overflow... always false
handle_overflow(x); // Let's delete this dead code.
}
Then, what actually happens:
unsigned u = some_computation();
int x = u;
x += 42;
This is insane.
- deleted 9y ago[deleted]
- smitherfield 9y agoA correction: a compiler would not be able to assume that `x` is always positive because casts between signed and unsigned integer types are based on their binary representation (what computers see), not their value (what humans see).[1] [1] https://wandbox.org/permlink/dDDAJjOlm50GD1PW https://wandbox.org/permlink/dDDAJjOlm50GD1PW It would be able to (correctly) make that assumption if `x` were a long, assuming 64-bit longs and 32-bit int/unsigneds.
- int_19h 9y agoIn the C standard, a cast from unsigned to signed integer is undefined behavior if it overflows. So the compiler can, indeed, assume that "x" is always positive in the code snippet above - if the value of "u" is such that it would require signed wraparound when initializing "x", the rest of the program is U.B., and so that possibility doesn't even have to be considered.
- smitherfield 9y agoThis is untrue; see section 6.3.1.3: When a value with integer type is converted to another integer type ... [if] the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised. http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf So casts from unsigned to signed must have a well-defined result, but the implementation can choose how to define it. You could in theory have an implementation that defines that casts from unsigned to signed are always positive,[1] but since that's not how GCC and every other mainstream (existing?) compiler defines it, they are not allowed to assume the result of a cast from an arbitrary unsigned integer to a signed integer of equal width is positive. [1] In which case the compiler would be allowed to assume that unsigned-to-signed casts are never negative. This assumption would however be both safe and correct, and would have nothing to do with UB.
- Avernar 9y agoI always wished C gave access to the overflow and carry flags. Would have made a lot of things simpler.
- Bromskloss 9y ago> // It's a 2's complement machine, this'll work Let's see, that's not an assumption you can make in C, or is it? I seem to remember that a compiler is allowed to present to the programmer at least one or two representations other than two's complement.
- int_19h 9y agoFrom C99 on, it's either one of: two's complement, ones' complement, or sign + magnitude.
- Bromskloss 9y agoThat's sounds familiar, so it's probably what I've read. What did previous versions say?
- int_19h 9y ago"The type char, the signed and unsigned integer types. and the enumerated types are collectively called integral types. The representations of integral types shall define values by use of a pure binary numeration system." And a footnote on that: "A positional representation of integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral powers of 2, except perhaps the bit with the highest position."