3 ms·
Detect on add? Not sure. Detect before add? Simple! bool int_add_safe(int a, int b) { if (a >= 0 && b >= 0) return INT_MAX - a >= b; if (a <
by forrestthewoods 12y ago
Detect on add? Not sure. Detect before add? Simple!
bool int_add_safe(int a, int b) {
if (a >= 0 && b >= 0)
return INT_MAX - a >= b;
if (a < 0 && b < 0)
return INT_MIN - a <= b;
return true;
}
If you ever have an instance that will result in an overflow you've got some kind of bug on your hand. Or at least some kind of circumstance that requires special handling. You don't want to overflow, not perform the add, or perform the add and discard the overflow. All three sucks and sweep a bug under the rug in some instance. Computers suck sometimes. :(
- nly 12y agoIt's possible to simplify your code. bool int_add_safe(int a, int b) { if (b < 0) { return (a >= INT_MIN - b); } else { return (a <= INT_MAX - b); } } Codegen comparison: http://goo.gl/Tgj7nu http://goo.gl/Tgj7nu (If you switch to GCC it makes a mess of your version). You're right in that all portable solutions suck, but on x86 it will certainly be faster just to do the add and check the overflow flag.
- TheLoneWolfling 12y agoNeither of those two compile down to what I imagine would be the best on x86, namely an add and then a check of the overflow flag. Is there any portable version that compiles down to that on GCC or Clang on x86?
- acqq 12y agoOnce you have a function consistently used in your code the portable version can be used for the targets for which you don't provide an asm implementation, and the asm (or the solution customized to the compiler) can be selected implementation otherwise, covering the most common processors of today.
- Someone 12y agoAlternatively, bug the compiler writers to make their compiler recognise that portable version. That way, you don't have to maintain all those special code paths. Getting the compiler writers to help you is easier if your project is significant, or if you use a portable version that a big open source project uses.
- acqq 12y agoMy proposal costs the implementer just a few #if lines in one file. Your alternative costs much more people much more time, and the gain is then just... the implementer saves a few #ifs.
- TheLoneWolfling 12y agoBy that logic most HLLs shouldn't have been made. Remember - write once run many times. Implementing it in GCC / etc once means that many people won't have to do it themselves - especially as it's far more likely that one implementation will be bug-free than many people writing their own.
- acqq 12y agoIt's not the feature that anybody would use as is, when you'd use it you'd prefer to call the function. But then what's behind the function is irrelevant for the users of the function. We don't force compiler authors to put in the compiler what can be nicely put in the libraries. It's: write one header with a few #if's once, everybody use it, whenever she needs it. You'd just call is_safe_to_add_ints( s, t[i] ) and be sure that on the common platform it's optimal thanks to the #if's in the header, and not write bool bsafe = (t[i] < 0) ? s >= INT_MIN - t[i] : s <= INT_MAX - t[i]; every time you'd want to check if the addition would be safe.
- Someone 12y agoBut you want if( !canSafelyAdd(a,b)) return ERROR; c = a + b; To compile down to an add and a check of the overflow bit. For that, you need help from the compiler. There are many examples where compilers special-case what is in a library. For example, compilers know they do not have to call strlen every time through this loop: for(int i = 0; i < strlen(s); ++i)
- acqq 12y agoNice, with the conditional operator and a single return it's even terser: bool is_safe_to_add_ints( int a, int b ) { return b < 0 ? a >= INT_MIN - b : a <= INT_MAX - b; }
- vegedor 12y agoCan e.g. GCC detect a beforehand check and transform it to a less complex check of the carry bit where supported (i.e. anywhere)?