When the standard says it’s undefined behavior, it means it. Anything can happen. “Anything” includes “usually integers wrap around, but on occasion weird stuff happens”.
Yes, on x86 CPUs, integers usually wrap the way you expect. This is one of those exceptions. The compiler assumes you won’t cause undefined behavior, and optimizes away the loop test. If you really want wraparound, pass -fwrapv
to g++
or gcc
when compiling; this gives you well-defined (twos-complement) overflow semantics, but can hurt performance.