It is impossible to detect and prevent overflow at compile time in the general case. There as specific circumstances where obvious overflows can be detected at compile time, such as those occurring during constant expression evaluation, and compilers usually report such problems.
Note that overflow is a problem for signed arithmetic in C. Unsigned arithmetic is performed modulo the power of 2 one past the maximum value of the promoted type.
What compilers do is assume that signed arithmetic performed as coded by the programmer will not overflow and optimize the code based on this assumption. For example the following test can be omitted by aggressive optimizers:
int test(int x) {
if (x + 1 > x) {
/* this is not a way to test for potential wrap-around
* since overflow is UB, the compiler can assume that incrementing
* an int always evaluates to a larger int.
*/
return x + 1;
}
return 0;
}
Detecting overflow at runtime is not specified in the C Standard. Code generators can add instructions for this purpose at a relatively low overhead to perform specific overflow handling. Other languages do this, but many C developers are reluctant to have even the smallest overhead for something they wrongly assume to never happen. It is useful to have this as a debug mode, and modern gcc and clang compilers provide sanitize options for address checking and other problems. For example you should check -fsanitize=undefined
:
For unsigned overflow, runtime detection would be possible via extra generated code that checks the processor flags, but since the behavior is defined, the sanitization options seem to not care about this type of overflow.
A different approach may be more appropriate for your purpose: gcc provides built-in functions to perform signed and unsigned arithmetic and report overflow at runtime: