-fwrapv做什么?

kta*_*tal 11 c binary gcc

任何人都可以提供一些代码示例,当使用fwrapv vs编译时,它们的行为会有所不同.

它说--fwrapv应该"假设加法,减法和乘法的带符号算术溢出,使用二进制补码表示包装."

但每当我尝试溢出时,结果与fwrapv相同或不同.

Azi*_*ziz 8

想想这个功能:

int f(int i) {
    return i+1 > i;
}
Run Code Online (Sandbox Code Playgroud)

从数学上讲,i+1应始终大于i任何整数i.但是,对于32位int,有一个值i使该语句为false,即2147483647(即0x7FFFFFFFie INT_MAX).在该数字中加一个将导致溢出,根据2的恭维表示,新值将环绕并变为-2147483648.因此,i+1>1变得-2147483648>2147483647虚假.

当你没有-fwrapv编译时,编译器将假设溢出是'非换行'并且它将优化该函数以始终返回1(忽略溢出情况).

当你编译-fwrapv,函数将不会被优化,并且它将具有加1和比较这两个值的逻辑,因为现在溢出是'换行'(即溢出的数字将根据2的补码表示进行换行).

  • @ktal我假设编译器优化处于启用状态(我使用了-O3)。[这里是两个编译代码的比较](https://godbolt.org/g/LvBqEh) (2认同)

R..*_*R.. 5

for (int i=0; i>=0; i++)
    printf("%d\n", i);
Run Code Online (Sandbox Code Playgroud)

使用-fwrapv,循环将在INT_MAX迭代后终止。没有它,它会做任何事情,因为未定义的行为是通过对i++when i是否具有value的评估来无条件调用的INT_MAX。实际上,优化的编译器可能会忽略循环条件并产生无限循环。