Think of this function:
int f(int i) {
return i+1 > i;
}
Mathematically speaking, i+1
should always be greater than i
for any integer i
. However, for a 32-bit int
, there is one value of i
that makes that statement false, which is 2147483647
(i.e. 0x7FFFFFFF
, i.e. INT_MAX
). Adding one to that number will cause an overflow and the new value, according to the 2's compliment representation, will wrap-around and become -2147483648
. Hence, i+1>i
becomes -2147483648>2147483647
which is false.
When you compile without -fwrapv
, the compiler will assume that the overflow is 'non-wrapping' and it will optimize that function to always return 1
(ignoring the overflow case).
When you compile with -fwrapv
, the function will not be optimized, and it will have the logic of adding 1 and comparing the two values, because now the overflow is 'wrapping' (i.e. the overflown number will wrap according to the 2's compliment representation).
The difference can be easily seen in the generated assembly - in the right pane, without -fwrapv
, function always returns 1
(true
).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…