有没有人能提供一些代码示例,当使用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,函数总是返回1true)。

10-07 20:34