Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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. :(



It'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 (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.


Nice, 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;
    }


Neither 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?


Once 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.


Alternatively, 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.


My 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.


By 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.


It'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.


But 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)


The enough help you need is, in the implementation of the library function #if X86 #if GCC etc and then the assembly for each case, otherwise the slow but standard implementation. And that's one file, the code never to be directly used but by function name. It's already done this way in the current libraries for a lot processor specific stuff.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: