A strong answer
A fixed-width integer has a fixed range. A signed 32-bit integer uses two's complement: the top bit is worth −2³¹ and the others keep their positive weights, so it holds −2,147,483,648 to 2,147,483,647. When an addition produces a result outside that range, the processor still produces 32 bits. The carry out of the top bit is lost, so 2,147,483,647 + 1, which is 0x7FFFFFFF + 1, becomes 0x80000000, the bit pattern for −2,147,483,648. The processor sets an overflow flag but doesn't stop.
What the program sees depends on the language. Java, C# and Go define signed overflow to wrap around. C and C++ make signed overflow undefined behavior, so the optimizer may assume it never happens, while unsigned arithmetic wraps. Rust panics in debug builds and wraps in release builds, and offers checked_add, wrapping_add and saturating_add to choose explicitly. Python integers have no fixed width, and JavaScript numbers are doubles that stay exact only up to 2⁵³.
Overflow causes real bugs: binary search computing (lo + hi) / 2 on huge arrays, size calculations such as count * element_size that wrap to a small number and lead to a too-small allocation, and timestamps or counters that pass the end of their range. The fixes are to choose a wide enough type, rearrange the arithmetic (lo + (hi - lo) / 2), or use checked operations where the inputs aren't trusted.
What the interviewer is listening for
- Two's complement, and that the hardware keeps the low bits.
- That the result depends on the language, with C's undefined behavior as the notable exception.
- At least one concrete bug that overflow causes, and a fix for it.
Common mistakes
- Saying the program crashes. In most languages it silently produces a wrong number.
- Assuming every language behaves like Java, or that Python has the same limits.
- Fixing the symptom with a bigger type without asking whether the inputs are trusted, which matters most for size calculations.