当使用严格的溢出标志编译以下内容时,它告诉我,在第二次测试中 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;
最佳答案
编辑:我删除了第一个答案,因为它无效。这是全新的版本。感谢@Neil Kirk 指出我的错误。
问题的答案在这里:https://stackoverflow.com/a/18521660/2468549
GCC 总是假设,带符号的溢出永远不会发生,并且,基于这个假设,它(总是)优化内部 if (r < 0)
block 。
如果你转-Wstrict-overflow
上,然后编译器发现,在 r = -r
之后r < 0
可能仍然是真的(如果 r == -2^31
最初),这会导致错误(错误是由基于溢出从不发生的假设的优化引起的,而不是溢出可能性本身 - 这就是 -Wstrict-overflow
的工作方式) .
关于c++ - g++ 严格溢出、优化和警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22798709/