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

of course it is possible. One must validate the input before performing arithmetic on signed integers.


The compiler is allowed to assume that the data will never overflow so it is also allowed to get rid of overflow checks. Now imagine writing a complex validation routine that if it were violated would result in undefined behavior for every value that the validation rejects, a sufficiently smart compiler is allowed to simply remove your validation code, leaving you with no validation whatsoever.


It can get rid of checks that test whether the results of a previous operation have overflowed. It can't eliminate checks that test whether a subsequent operation will overflow and abort because that would be changing semantics.

C is an absolute minefield of undefined behavior, but let's be accurate about the things it does wrong.


There are several ways to do overflow checks safely (i.e. without undefined behavior), though the ergonomics are not always ideal.

C23 somewhat improves the situation with <stdckdint.h>, a standardized version of GCC’s __builtin_add_overflow and friends. That has ergonomics issues too due to its verbosity, but at least it’s hard to screw up.


The compiler is allowed to assume that if x and y are signed ints:

   if (x < 0 || y < 0) return -1;
   return x * y;
Will not overflow. And if you try to check for overflow with:

   if (x < 0 || y < 0) return -1;
   if (x * y < 0) return -2;
   return x*y;
Then yes, the compiler is within spec to remove your check because the only situation in which you could hit that check would be after signed integer overflow, which it is allowed to assume won't happen.

One way to implement this check in GCC where the compiler will respect it would be:

   if (x < 0 || y < 0) return -1;
   int z;
   if (__builtin_smul_overflow(x, y, &z)) return -2;
   return z;


That doesn’t sound like sound logic to me. The compiler assumes that at the point you have the arithmetics, they won’t overflow. This hinges upon all the former state of the program. If it can prove that the given integers won’t overflow (e.g. due to a previous, redundant check) then it can indeed remove a conditional, but the compiler can’t change the observable behavior of the program.


It can't (correctly) remove checks that would have prevented the undefined behavior, because that is changing the semantics of a program that (as written) does not trigger undefined behavior.




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

Search: