A trap for the inattentive: why is unsigned int a time bomb?
\n\nEvery C++ developer sooner or later encounters a situation where numbers behave like angry rabbits — endlessly jumping from positive to zero. We are talking about unsigned int overflow. Unlike its signed counterpart (signed int), unsigned overflow in C++ is strictly defined by the standard — it is not UB (undefined behavior). The number simply wraps around modulo 2N. But this does not make the error any less fatal.
Imagine: you are calculating an account balance, the number of elements in an array, or a timer's runtime. One accidental overflow — and the application logic collapses. The question in the title "How do I detect unsigned integer overflow?" gathered thousands of views on Stack Overflow for a reason. Let's analyze three approaches to overflow detection: from naive (but working) to professional.
\n\nWhy don't standard checks work?
\n\nThe first thing that comes to a beginner's mind:
\n\nunsigned int a = UINT_MAX;\nunsigned int b = 1;\nif (a + b < a) // Naive check\n std::cout << "Overflow!";\n\nThis code works, but only for addition. For multiplication, subtraction, or mixed types, the logic breaks. Additionally, the compiler may consider such a check redundant and remove it during optimization. Especially if the types are signed. Don't rely on magic — write explicitly.
\n\nApproach #1: Pre-operation arithmetic (Pre-check)
\n\nThe most reliable way is to check for the possibility of overflow before performing the operation. For adding two unsigned numbers, the condition is simple:
\n\nIf a + b can overflow, then a > (UINT_MAX - b).
#include <climits>\n#include <iostream>\n\nbool will_add_overflow(unsigned int a, unsigned int b) {\n return a > UINT_MAX - b;\n}\n\nint main() {\n unsigned int x = 4000000000;\n unsigned int y = 500000000;\n \n if (will_add_overflow(x, y)) {\n std::cerr << "Error: overflow during addition!\\n";\n } else {\n std::cout << "Result: " << x + y << "\\n";\n }\n return 0;\n}\n\nMultiplication — more complex
\nFor multiplication, the check is slightly trickier: a > UINT_MAX / b (and don't forget about division by zero).
bool will_mult_overflow(unsigned int a, unsigned int b) {\n if (b == 0) return false; // Multiplication by zero is safe\n return a > UINT_MAX / b;\n}\n\nPros: Cross-platform, full control, no hidden dependencies.
\nCons: Need to write separate functions for each operation. The code becomes cumbersome.
Approach #2: Post-operation check (Post-check)
\n\nThe C++ standard guarantees that for unsigned types, the result of an operation is (a + b) mod 2^N. Therefore, we can perform the operation and then check if the value has "wrapped around".
#include <iostream>\n#include <limits>\n\ntemplate<typename T>\nbool add_overflow(T a, T b, T& result) {\n result = a + b;\n return result < a; // Key trick\n}\n\nint main() {\n unsigned int res;\n if (add_overflow(4000000000u, 500000000u, res)) {\n std::cout << "Overflow detected!\\n";\n } else {\n std::cout << "OK: " << res << "\\n";\n }\n return 0;\n}\n\nImportant: This trick works only if a and b are of the same unsigned type. For uint32_t — excellent. For a mix of unsigned int and int — failure.
Trap for subtraction
\nFor subtraction, the condition is reversed: result > a.
template<typename T>\