以下是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)
由于存在两个溢出,编译器可能会以与环绕假设不兼容的方式优化或转换两个比较.
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。
综上所述,上述代码经过编译器优化后可能会失败。