这段代码中的第二个溢出在哪里

Ank*_*wal 6 c

以下是GNU C参考手册第74页的代码:

如果您的代码使用带符号循环索引,请确保索引不会溢出,以及从索引派生的所有已签名表达式.这是一个有问题的代码的例子,有两个溢出实例.

for( i = INT_MAX - 10 ; i <= INT_MAX; i++)
    if( i+1 < 0 ) //first overflow
    {
        report_overflow();
        break; 
    }
Run Code Online (Sandbox Code Playgroud)

由于存在两个溢出,编译器可能会以与环绕假设不兼容的方式优化或转换两个比较.

sha*_*hmo 4

GNU C 参考手册的意思是有两种可能的溢出。第一个是i++声明

for( i = INT_MAX - 10 ; i <= INT_MAX; i++)
Run Code Online (Sandbox Code Playgroud)

第二个将i+1

if( i+1 < 0 ) //first overflow
Run Code Online (Sandbox Code Playgroud)

示例 C 代码避免了永恒循环

if( i+1 < 0 ) //first overflow
{
    report_overflow();
    break; 
}
Run Code Online (Sandbox Code Playgroud)

一段代码,并且要做到这一点,您依赖于签名的环绕行为。

然而,A.3 附录告诉您,您不应该依赖签名的环绕行为,因为优化器会利用其未定义的行为,并可能生成行为与您期望不同的代码。一段代码就是这种情况if( i+1 < 0 ),它依赖于当iis时会发生回绕INT_MAX

综上所述,上述代码经过编译器优化后可能会失败。

  • +1你正确地说“你不应该依赖环绕行为”,也许重要的是要说明这种情况,因为变量是有符号的,而如果变量是无符号的,则可以保证环绕。 (2认同)
  • @mvp 这里的要点是,优化器(而不是体系结构)在使用有符号整数时依赖回绕时可能会产生“奇怪”的行为。最好在多个线程中进行描述,例如 [1](http://stackoverflow.com/a/7682539/2436175) [2](http://stackoverflow.com/a/4240878/2436175) [3](http ://stackoverflow.com/questions/19842215/wrap-around-explanation-for-signed-and-unsigned-variables-in-c) (2认同)