C++ integer arithmetic overflow
-
The usual way is after adding two positive numbers together, check if the result is negative. If it is, you've overflowed. You can also, if you're adding two 32-bit numbers together, cast them both to 64-bit, then add them and check if the resulting 64-bit value is greater than INT32_MAX. Judy
Be wary of strong drink. It can make you shoot at tax collectors - and miss. Lazarus Long, "Time Enough For Love" by Robert A. Heinlein
As mentioned above, specifically undefined behavior might turn out in such a way that the "signed"ness does not necessarily flip as you would expect. Having said that, I don't know of a CPU/compiler that doesn't simply let the integers wrap around because that is still the easiest to implement. I was almost trying to propose some right-shift logic trick to check, but, the right-shift is, in fact, undefined for signed integers as well and may give invalid results. In assembly it's plain simple, you typically check the carry or overflow flag for unsigned or signed integers, respectively. Finally, a watertight solution would be to cut every integer in two halves using masks and shifts, then craft your own carry- and overflow logic. I'm too lazy to work it out in detail but I'm positive that all the information you need to detect overflow is in the high bits of the upper sum. Something like, upper half, or upper half + 1 bits must turn out equal, and if not, there is overflow.
-
An ounce of prevention is worth a pound of cure. Take either addend and subtract it from the maximum. If the result is smaller than the other addend, you will overflow. If Max - A < B, then A + B > Max // OVERFLOW
Whether an ounce is more than a pound depends on foreign imperial units, and scales that might overflow. Having said that, the method is properly defined in C(++) for unsigned all integers, using each their respective maximums, and easier than what I proposed.
-
may i inquire how C++ integer arithmetic is performed in your code so as to prevent / detect / report overflow ?
There's many discussions of this on many StackOverflow and other threads. Some compilers support options to [enable throwing exceptions on overflow](https://stackoverflow.com/questions/3679047/integer-overflow-in-c-standards-and-compilers) including GCC (-ftrapv) or checked intrinsic options. If you're willing to wait, the [C23 standard](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3047.pdf) includes a proposal for a stdckdint library with functions for performing checked integer math. Otherwise, you probably need to either find a 3rd party library that does this (or write your own methods where you can use one of many techniques depending on your performance requirements). Also, [C# supports checked expressions](https://stackoverflow.com/questions/2056445/no-overflow-exception-for-int-in-c) as either a compiler option or a local code block, in case that's an option.
-
There's many discussions of this on many StackOverflow and other threads. Some compilers support options to [enable throwing exceptions on overflow](https://stackoverflow.com/questions/3679047/integer-overflow-in-c-standards-and-compilers) including GCC (-ftrapv) or checked intrinsic options. If you're willing to wait, the [C23 standard](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3047.pdf) includes a proposal for a stdckdint library with functions for performing checked integer math. Otherwise, you probably need to either find a 3rd party library that does this (or write your own methods where you can use one of many techniques depending on your performance requirements). Also, [C# supports checked expressions](https://stackoverflow.com/questions/2056445/no-overflow-exception-for-int-in-c) as either a compiler option or a local code block, in case that's an option.
i have written functions for addition and subtraction with signature
template requires integral&& integral&& integral sumType addition(augendType augend, addendType addend, OPTIONAL\_MATH\_CLIMITS\_TYPE(sumType) limits =EMPTY\_OPTIONAL\_MATH\_CLIMITS(sumType));
it ensures if the requested result type can store the result no overflow will result no matter the argument size or sign . also variadic forms . these variadic forms minimize the chance of overflow by rearranging the arguments exempli gratia MAXINT + MAXINT - MAXINT becomes MAXINT - MAXINT + MAXINT . i am considering writing a variadic function which accepts all the arithmetic operators as arguments and utilizes the above techniques . my original post was to discern if such would be usefol to others and to learn of other options for myself .
-
may i inquire how C++ integer arithmetic is performed in your code so as to prevent / detect / report overflow ?
I would suggest having a look at the built-in functions of the compilers that feature an overflow check. According to this post most recent compilers (GCC, Clang, Intel, MSVC) provide them. Documentation: https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
bool __builtin_add_overflow (type1 a, type2 b, type3 *res)
bool __builtin_sub_overflow (type1 a, type2 b, type3 *res)
bool __builtin_mul_overflow (type1 a, type2 b, type3 *res)bool __builtin_add_overflow_p (type1 a, type2 b, type3 c)
bool __builtin_sub_overflow_p (type1 a, type2 b, type3 c)
bool __builtin_mul_overflow_p (type1 a, type2 b, type3 c)