iTranslated by AI
Integer Overflow Checking in C
In C, signed integer overflow is undefined behavior. However, there are cases where you want to know if an overflow occurred rather than just dismissing it as undefined behavior. In the upcoming C standard, C23, features to detect (signed or unsigned) integer overflow are expected to be provided.
GCC Extensions
GCC/Clang provide built-in functions as extensions to notify you of the presence or absence of overflow.
- Integer Overflow Builtins (Using the GNU Compiler Collection (GCC))
- Checked Arithmetic Builtins - Clang Language Extensions
bool __builtin_add_overflow(type1 a, type2 b, type3 *res);
bool __builtin_sadd_overflow(int a, int b, int *res); // Versions for long and long long also exist
bool __builtin_uadd_overflow(unsigned int a, unsigned int b, unsigned int *res); // Versions for unsigned long and unsigned long long also exist
// Similar for sub and mul
These built-in functions perform calculations by treating the first and second arguments as exact (infinite precision) integers, cast the result to the type pointed to by the third argument, and store it there. If the result of the cast is exact, false is returned; if the result of the cast is inexact (i.e., an overflow occurs), true is returned.
The first one (the one taking type1, type2, type3) cannot be applied to bool or enum types.
For signed integers represented in two's complement, division can also cause overflow, but GCC does not provide a check for it. This is probably because checking a == INT_MIN && b == -1 is sufficient.
Libraries
I'll also introduce some existing libraries (borrowing from N2683).
It seems Windows has something called intsafe.h.
There is also a library called SafeInt.
Boost includes a library called Safe Numerics.
Methods in C23
Towards C23, various proposals for "safe integer arithmetic" were made in N2683: Towards Integer Safety. Among these, the following three will be incorporated into C23:
#include <stdckdint.h>
bool ckd_add(type1 *result, type2 a, type3 b);
bool ckd_sub(type1 *result, type2 a, type3 b);
bool ckd_mul(type1 *result, type2 a, type3 b);
The main differences from the GCC extensions are the changed order of arguments and the addition of char (with indeterminate sign) and _BitInt to the excluded integer types, in addition to bool and enum.
That is, the result of the calculation of a and b is stored in *result, and it returns true if an overflow occurs.
Since the C language does not have overloading, these three are defined as macros.
For other features of C23, please refer to:
Discussion