3 ms·
A comment below reminded me of these: https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Buil
by efaref 10y ago
A comment below reminded me of these: https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins..., which are close, but have an insane API as they replace your arithmetic operations with ugliness.
I think they can be fixed with sensible macros, though:
#define ADDITION_WOULD_OVERFLOW(a, b) \
({ typeof((a) + (b)) __r; __builtin_add_overflow((a), (b), &__r); })
Hopefully the compiler would optimise:
if (ADDITION_WOULD_OVERFLOW(a, b))
{
return 0;
}
return a + b;
to only do the addition once.
- efaref 10y agoI just tried this, and GCC6 does indeed optimise this correctly: 0000000000400560 <maybe_overflow>: 400560: 01 f7 add %esi,%edi 400562: 70 03 jo 400567 <maybe_overflow+0x7> 400564: 89 f8 mov %edi,%eax 400566: c3 retq 400567: 31 c0 xor %eax,%eax 400569: c3 retq
- Kristine1975 10y agoHow about: #define ADD_OR_DEFAULT(a, b, d) \ ({ typeof((a) + (b)) r; __builtin_add_overflow((a), (b), &r) ? (d) : r; }) and then: return ADD_OR_DEFAULT(a, b, 0); P.S: Names beginning with two underscores are reserved for the implementation.
- efaref 10y agoThe problem with solutions like this is that they break the abstraction of using algebraic notation for calculations. We're conditioned to expect calculations to be written in algebraic notation, and indeed one of the original selling points of C is that it lets you express calculations in that form. To undo that is a massive shame. The calculation itself absolutely MUST look like this: a + b While maybe it's not too bad for simple addition, think of compound expressions with multiple terms.