有没有人能提供一些代码示例,当使用fwrapv vs编译时,它们的行为会有所不同。
它说-fwrapv应该“假设加法、减法和乘法的有符号算术溢出,使用two的补码表示进行包装。”
但每当我试图溢出的结果是一样的,无论有没有fwrapv。
最佳答案
想想这个功能:
int f(int i) {
return i+1 > i;
}
从数学上讲,对于任何整数
i+1
来说,i
都应该大于i
。但是,对于32位int
,有一个值i
使该语句为false,即2147483647
(即0x7FFFFFFF
,即INT_MAX
)。在这个数字上加一个将导致溢出,根据2的恭维表示,新值将被包围并变为-2147483648
。因此,i+1>1
变为-2147483648>2147483647
这是错误的。当您在没有
-fwrapv
的情况下编译时,编译器将假定溢出是“非包装”的,并且它将优化该函数以始终返回1
(忽略溢出情况)。当您使用
-fwrapv
编译时,函数将不会被优化,它将具有添加1和比较两个值的逻辑,因为现在溢出是“包装”(即溢出号将根据2的补充表示进行包装)。在右窗格的generated assembly-中可以很容易地看到差异,如果没有
-fwrapv
,函数总是返回1
(true
)。