3 ms·
GCC -O1 and clang -O1 will both optimize this function under the assumption that inputs that cause signed integer overflow are never passed: int will_overf
by Retr0id 5mo ago
GCC -O1 and clang -O1 will both optimize this function under the assumption that inputs that cause signed integer overflow are never passed:
int will_overflow(int a, int b) {
int sum = a + b;
if (b > 0 && sum < a)
return 1;
return 0;
}
- mbrock 5mo agoRight, good example, and both GCC and Clang offer well understood parameters for deciding, per compilation unit, what behavior you want for signed overflow (-fwrapv, -fno-strict-overflow, etc), so in reality it's quite far from spooky arbitrary nasal demons.
- skydhash 5mo agoWouldn’t be better to check both inputs before against the max value of that type instead of actually doing the overflow?
- Retr0id 5mo agoThere are lots of better ways of doing this, but knowing why this one is bad/wrong requires the mental model described upthread. (But also, what you describe would be incorrect, since two <MAX values can add to a value that is >MAX, and overflow)
- skydhash 5mo ago> But also, what you describe would be incorrect, since two <MAX values can add to a value that is >MAX, and overflow I was maybe unclear. I meant, if you know a sum can introduce overflow (because you have a check right after), why not check the inputs before doing the sum, instead of checking the sum?
- mbrock 5mo agoYou can do something like (y > 0 && x > INT_MAX - y) || (y < 0 && x < INT_MIN - y) and hope the optimizer turns it back into just checking the result. Or you use -fwrapv to concretize the ISO ambiguity and specify the natural two's complement semantics, checking overflow with the classic Hacker's Delight formula; ((x ^ s) & (y ^ s)) < 0 But the best way is to use the intrinsic __builtin_add_overflow or, depending on compiler support, its C23 standardization via <stdckdint.h> and ckd_add etc.