2014-04-01 32 views
2

编译时有严格的溢出标志下面,它告诉我,2号测试的R可能不是,我认为它可能是:克++严格溢出,优化和警告

int32_t r(my_rand()); 
    if(r < 0) { 
     r = -r; 
     if(r < 0) { // <-- error on this line 
      r = 0; 
     } 
    } 

错误是:

/build/buildd/libqtcassandra-0.5.5/tests/cassandra_value.cpp: 
    In function 'int main(int, char**)': 
/build/buildd/libqtcassandra-0.5.5/tests/cassandra_value.cpp:2341:13: 
    error: assuming signed overflow does not occur when simplifying 
    conditional to constant [-Werror=strict-overflow] 
     if(r < 0) { 
     ^

我不明白的是:为什么不会在这之前的行上产生错误?因为当我这样做的时候确实会发生溢出,对吧?

r = -r; 

回答

2

编辑:我删除了我的第一个答案,因为它是无效的。这是完全新的版本。感谢@Neil Kirk指出我的错误。

回答的问题是在这里:https://stackoverflow.com/a/18521660/2468549

GCC总是假定,有符号数溢出并不会发生,以及在这一假设,(总是)优化了内部if (r < 0)块。

如果打开-Wstrict-overflow,然后编译器发现,那r = -rr < 0仍可能是真实的(如果r == -2^31开始),这将导致一个错误(错误是通过优化基于溢出从未的假设发生,没有造成通过溢出可能性本身 - 这就是-Wstrict-overflow的工作原理)。

+0

当'r = -2147483648'时,'-r'是什么? –

+0

有符号整数的范围是不对称的:从-2147483648到2147483647.因此,将-2147483648与0(在CPU /汇编程序语言级别上实现)相减(0 - ( - 2147483648)并检查符号标志)会导致溢出。 – Frax

+0

如果'r = -2147483648',那么'-r = 0'。这不是溢出吗? –