5 ms·
of course it is possible. One must validate the input before performing arithmetic on signed integers.
by compiler-guy 4y ago
of course it is possible. One must validate the input before performing arithmetic on signed integers.
- deleted 4y ago[deleted]
- imtringued 4y agoThe compiler is allowed to assume that the data will never overflow so it is also allowed to get rid of overflow checks. Now imagine writing a complex validation routine that if it were violated would result in undefined behavior for every value that the validation rejects, a sufficiently smart compiler is allowed to simply remove your validation code, leaving you with no validation whatsoever.
- deleted 4y ago[deleted]
- AlotOfReading 4y agoIt can get rid of checks that test whether the results of a previous operation have overflowed. It can't eliminate checks that test whether a subsequent operation will overflow and abort because that would be changing semantics. C is an absolute minefield of undefined behavior, but let's be accurate about the things it does wrong.
- comex 4y agoThere are several ways to do overflow checks safely (i.e. without undefined behavior), though the ergonomics are not always ideal. C23 somewhat improves the situation with <stdckdint.h>, a standardized version of GCC’s __builtin_add_overflow and friends. That has ergonomics issues too due to its verbosity, but at least it’s hard to screw up.
- dllthomas 4y agoIt can't (correctly) remove checks that would have prevented the undefined behavior, because that is changing the semantics of a program that (as written) does not trigger undefined behavior.
- kaba0 4y agoThat doesn’t sound like sound logic to me. The compiler assumes that at the point you have the arithmetics, they won’t overflow. This hinges upon all the former state of the program. If it can prove that the given integers won’t overflow (e.g. due to a previous, redundant check) then it can indeed remove a conditional, but the compiler can’t change the observable behavior of the program.
- jefftk 4y agoThe compiler is allowed to assume that if x and y are signed ints: if (x < 0 || y < 0) return -1; return x * y; Will not overflow. And if you try to check for overflow with: if (x < 0 || y < 0) return -1; if (x * y < 0) return -2; return x*y; Then yes, the compiler is within spec to remove your check because the only situation in which you could hit that check would be after signed integer overflow, which it is allowed to assume won't happen. One way to implement this check in GCC where the compiler will respect it would be: if (x < 0 || y < 0) return -1; int z; if (__builtin_smul_overflow(x, y, &z)) return -2; return z;