Earlier quoted context omitted.
As you say, detecting the overflow is easy, but efficiently handling it is not. It adds a branch to every single arithmetic operation, and it makes it much harder for the compiler to optimise things e.g. it is hard to vectorise a loop summing an array, if every + has a conditional branch on the overflow flag. (Also, I believe it introduces a lot of data dependencies, getting in the way of the out-of-order execution o…
To handle the overflow on the places where you want to handle them, modern processor doesn't have any problem with an additional jump instruction. Also, modern compilers could optimize the checks away if they aren't used. In effect, implementing overflow checks definitely won't turn your C speed (1s) code in a Python speed (40s) code. I estimate it wouldn't be even two times slower in most of the use cases. It's cert…
In his "We Need Hardware Traps for Integer Overflow"[0], Regher quotes 5% to 100% overhead for languages such as JS or Racket, and that a "highly tuned" checker would likely be in the 5% range. Playing with arithmetics-heavy programs and Rust's checked_* (which are backed by LLVM's overflow intrinsics[1]) I got anywhere from 5 to 40% performance loss IIRC.
That's not a lot, but at the same time when you're competing with languages specifically not paying those 5%, a 5% hit on all computations is not going to get you much love.
Which is why Rust currently lets you do that (via num::Checked* and num::Saturating) but uses overflowing default semantics.
[0] http://blog.regehr.org/archives/1154
[1] http://llvm.org/docs/LangRef.html#arithmetic-with-overflow-i...