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

  volatile int b = 23;
  if (a + b < b) overflow;
Tada. That's how you get around the GCC optimization issue in practice. I suppose though this doesn't suite as a proper answer since overflowing as a result of adding two signed integers results in undefined behavior..

The solution is to cast the integers to unsigned and then do the overflow check. The following two standard sections should demonstrate the standards-compliance of the code below.

> ANSI C99 6.2.5 Types #9

> A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

> ANSI C99 6.3.1.3 Signed and unsigned integers #2

> Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

---------

  // shift the MSB to the LSB
  #define signof(x) (!!((x) & INT_MIN))

  int x, y;

  // bits stay the same thanks to 6.3.1.3
  unsigned int a = (unsigned int) x;
  unsigned int b = (unsigned int) y;

  unsigned int sign_a = signof(a);
  unsigned int sign_b = signof(b);

  // a+b should have the same sign as a and b, otherwise an overflow/underflow has occurred
  // note that a+b is well defined for unsigned ints according to 6.2.5 #9
  if (sign_a == sign_b && signof(a+b) != sign_a) overflow;
The code for checking overflow on unsigned ints is trivial:

  unsigned int a, b;
  if (a + b < a) overflow;


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

Search: