Skip to content

Instantly share code, notes, and snippets.

@antirez
Created February 21, 2012 14:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antirez/1876875 to your computer and use it in GitHub Desktop.
Save antirez/1876875 to your computer and use it in GitHub Desktop.
/* If you compile with -O2 the code will print "Wrong behavior", compiling
* with -O0 the code will print "Correct behavior".
*
* Tested with:
* Apple clang version 2.1 (tags/Apple/clang-163.7.1) (based on LLVM 3.0svn)
* Target: x86_64-apple-darwin11.3.0
* Thread model: posix
*/
#include <stdio.h>
int getValue(long long *l) {
*l = -9223372036854775484LL;
return 1;
}
void bug(void) {
long long value, incr, oldvalue;
incr = -1000;
if (getValue(&value) != 1) return;
oldvalue = value;
value += incr;
if ((incr < 0 && value > oldvalue) || (incr > 0 && value < oldvalue)) {
printf("Correct behavior\n");
} else {
printf("Wrong behavior\n");
}
}
int main(void) {
bug();
}
@antirez
Copy link
Author

antirez commented Feb 21, 2012

I'm turning the old code into this one:

    oldvalue = value;
    if ((incr < 0 && oldvalue < 0 && incr < (LLONG_MIN-oldvalue)) ||
        (incr > 0 && oldvalue > 0 && incr > (LLONG_MAX-oldvalue))) {
        printf("Correct behavior\n");
    } else {
        printf("Wrong behavior\n");
    }
    value += incr;

Should be safe since it is guaranteed that all the parts never overflow.
LLONG_MIN-oldvalue can't overflow because oldvalue is guaranteed to be < 0
LLONG_MAX-oldvalue can't overflow because oldvalue is guaranteed to be > 0

Now trying it in practice :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment